mirror of
https://github.com/jellyfin/jellyfin
synced 2024-11-05 18:59:30 +00:00
Merge branch 'master' of https://github.com/MediaBrowser/MediaBrowser
This commit is contained in:
commit
411a0531e0
46 changed files with 620 additions and 117 deletions
63
MediaBrowser.Api/ConnectService.cs
Normal file
63
MediaBrowser.Api/ConnectService.cs
Normal file
|
@ -0,0 +1,63 @@
|
|||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Controller.Connect;
|
||||
using MediaBrowser.Controller.Net;
|
||||
using ServiceStack;
|
||||
|
||||
namespace MediaBrowser.Api
|
||||
{
|
||||
[Route("/Users/{Id}/Connect/Info", "GET", Summary = "Gets connect info for a user")]
|
||||
public class GetConnectUserInfo : IReturn<ConnectUserLink>
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Users/{Id}/Connect/Link", "POST", Summary = "Creates a Connect link for a user")]
|
||||
public class CreateConnectLink : IReturn<ConnectUserLink>
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||
public string Id { get; set; }
|
||||
|
||||
[ApiMember(Name = "ConnectUsername", Description = "Connect username", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
|
||||
public string ConnectUsername { get; set; }
|
||||
}
|
||||
|
||||
[Route("/Users/{Id}/Connect/Link", "DELETE", Summary = "Removes a Connect link for a user")]
|
||||
public class DeleteConnectLink : IReturn<ConnectUserLink>
|
||||
{
|
||||
[ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "DELETE")]
|
||||
public string Id { get; set; }
|
||||
}
|
||||
|
||||
[Authenticated]
|
||||
public class ConnectService : BaseApiService
|
||||
{
|
||||
private readonly IConnectManager _connectManager;
|
||||
|
||||
public ConnectService(IConnectManager connectManager)
|
||||
{
|
||||
_connectManager = connectManager;
|
||||
}
|
||||
|
||||
public object Get(GetConnectUserInfo request)
|
||||
{
|
||||
var result = _connectManager.GetUserInfo(request.Id);
|
||||
|
||||
return ToOptimizedResult(result);
|
||||
}
|
||||
|
||||
public void Post(CreateConnectLink request)
|
||||
{
|
||||
var task = _connectManager.LinkUser(request.Id, request.ConnectUsername);
|
||||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
|
||||
public void Delete(DeleteConnectLink request)
|
||||
{
|
||||
var task = _connectManager.RemoveLink(request.Id);
|
||||
|
||||
Task.WaitAll(task);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -195,7 +195,7 @@ namespace MediaBrowser.Api.Library
|
|||
}
|
||||
else
|
||||
{
|
||||
var user = _userManager.GetUserById(new Guid(request.UserId));
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var result = _libraryManager.GetVirtualFolders(user).OrderBy(i => i.Name).ToList();
|
||||
|
||||
|
|
|
@ -321,7 +321,7 @@ namespace MediaBrowser.Api.LiveTv
|
|||
|
||||
public async Task<object> Get(GetChannel request)
|
||||
{
|
||||
var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(new Guid(request.UserId));
|
||||
var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(request.UserId);
|
||||
|
||||
var result = await _liveTvManager.GetChannel(request.Id, CancellationToken.None, user).ConfigureAwait(false);
|
||||
|
||||
|
@ -406,7 +406,7 @@ namespace MediaBrowser.Api.LiveTv
|
|||
|
||||
public async Task<object> Get(GetRecording request)
|
||||
{
|
||||
var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(new Guid(request.UserId));
|
||||
var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(request.UserId);
|
||||
|
||||
var result = await _liveTvManager.GetRecording(request.Id, CancellationToken.None, user).ConfigureAwait(false);
|
||||
|
||||
|
@ -514,7 +514,7 @@ namespace MediaBrowser.Api.LiveTv
|
|||
|
||||
public async Task<object> Get(GetProgram request)
|
||||
{
|
||||
var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(new Guid(request.UserId));
|
||||
var user = string.IsNullOrEmpty(request.UserId) ? null : _userManager.GetUserById(request.UserId);
|
||||
|
||||
var result = await _liveTvManager.GetProgram(request.Id, CancellationToken.None, user).ConfigureAwait(false);
|
||||
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
</Compile>
|
||||
<Compile Include="BrandingService.cs" />
|
||||
<Compile Include="ChannelService.cs" />
|
||||
<Compile Include="ConnectService.cs" />
|
||||
<Compile Include="Dlna\DlnaServerService.cs" />
|
||||
<Compile Include="Dlna\DlnaService.cs" />
|
||||
<Compile Include="Library\ChapterService.cs" />
|
||||
|
|
|
@ -784,7 +784,7 @@ namespace MediaBrowser.Api.Playback
|
|||
get
|
||||
{
|
||||
#if __MonoCS__
|
||||
return false;
|
||||
return true;
|
||||
#endif
|
||||
|
||||
try
|
||||
|
|
|
@ -137,7 +137,7 @@ namespace MediaBrowser.Api
|
|||
public object Get(GetPlaylistItems request)
|
||||
{
|
||||
var playlist = (Playlist)_libraryManager.GetItemById(request.Id);
|
||||
var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(new Guid(request.UserId)) : null;
|
||||
var user = !string.IsNullOrWhiteSpace(request.UserId) ? _userManager.GetUserById(request.UserId) : null;
|
||||
|
||||
var items = playlist.GetManageableItems().ToArray();
|
||||
|
||||
|
|
|
@ -282,7 +282,7 @@ namespace MediaBrowser.Api
|
|||
UserId = request.UserId
|
||||
});
|
||||
|
||||
var user = _userManager.GetUserById(new Guid(request.UserId));
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
var fields = request.GetItemFields().ToList();
|
||||
|
||||
|
|
|
@ -245,7 +245,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
|
||||
foreach (var additionalUserInfo in session.AdditionalUsers)
|
||||
{
|
||||
var additionalUser = _userManager.GetUserById(new Guid(additionalUserInfo.UserId));
|
||||
var additionalUser = _userManager.GetUserById(additionalUserInfo.UserId);
|
||||
|
||||
await UpdatePlayedStatus(additionalUser, request.Id, true, datePlayed).ConfigureAwait(false);
|
||||
}
|
||||
|
@ -353,7 +353,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
|
||||
foreach (var additionalUserInfo in session.AdditionalUsers)
|
||||
{
|
||||
var additionalUser = _userManager.GetUserById(new Guid(additionalUserInfo.UserId));
|
||||
var additionalUser = _userManager.GetUserById(additionalUserInfo.UserId);
|
||||
|
||||
await UpdatePlayedStatus(additionalUser, request.Id, false, null).ConfigureAwait(false);
|
||||
}
|
||||
|
|
|
@ -402,7 +402,7 @@ namespace MediaBrowser.Api.UserLibrary
|
|||
|
||||
public async Task<object> Get(GetUserViews request)
|
||||
{
|
||||
var user = _userManager.GetUserById(new Guid(request.UserId));
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
// Get everything
|
||||
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
|
||||
|
|
|
@ -186,7 +186,7 @@ namespace MediaBrowser.Common.Implementations
|
|||
{
|
||||
if (_deviceId == null)
|
||||
{
|
||||
_deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId"));
|
||||
_deviceId = new DeviceId(ApplicationPaths, LogManager.GetLogger("SystemId"), NetworkManager);
|
||||
}
|
||||
|
||||
return _deviceId.Value;
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
@ -9,6 +11,7 @@ namespace MediaBrowser.Common.Implementations.Devices
|
|||
public class DeviceId
|
||||
{
|
||||
private readonly IApplicationPaths _appPaths;
|
||||
private readonly INetworkManager _networkManager;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
private readonly object _syncLock = new object();
|
||||
|
@ -67,7 +70,23 @@ namespace MediaBrowser.Common.Implementations.Devices
|
|||
|
||||
private string GetNewId()
|
||||
{
|
||||
return Guid.NewGuid().ToString("N");
|
||||
// When generating an Id, base it off of the app path + mac address
|
||||
// But we can't fail here, so if we can't get the mac address then just use a random guid
|
||||
|
||||
string mac;
|
||||
|
||||
try
|
||||
{
|
||||
mac = _networkManager.GetMacAddress();
|
||||
}
|
||||
catch
|
||||
{
|
||||
mac = Guid.NewGuid().ToString("N");
|
||||
}
|
||||
|
||||
mac += "-" + _appPaths.ApplicationPath;
|
||||
|
||||
return mac.GetMD5().ToString("N");
|
||||
}
|
||||
|
||||
private string GetDeviceId()
|
||||
|
@ -85,10 +104,11 @@ namespace MediaBrowser.Common.Implementations.Devices
|
|||
|
||||
private string _id;
|
||||
|
||||
public DeviceId(IApplicationPaths appPaths, ILogger logger)
|
||||
public DeviceId(IApplicationPaths appPaths, ILogger logger, INetworkManager networkManager)
|
||||
{
|
||||
_appPaths = appPaths;
|
||||
_logger = logger;
|
||||
_networkManager = networkManager;
|
||||
}
|
||||
|
||||
public string Value
|
||||
|
|
20
MediaBrowser.Controller/Connect/ConnectInvitationRequest.cs
Normal file
20
MediaBrowser.Controller/Connect/ConnectInvitationRequest.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
|
||||
namespace MediaBrowser.Controller.Connect
|
||||
{
|
||||
public class ConnectInvitationRequest
|
||||
{
|
||||
public string LocalUserId { get; set; }
|
||||
|
||||
public string Username { get; set; }
|
||||
|
||||
public string RequesterUserId { get; set; }
|
||||
|
||||
public ConnectUserType Type { get; set; }
|
||||
}
|
||||
|
||||
public enum ConnectUserType
|
||||
{
|
||||
LinkedUser = 1,
|
||||
Guest = 2
|
||||
}
|
||||
}
|
22
MediaBrowser.Controller/Connect/ConnectUser.cs
Normal file
22
MediaBrowser.Controller/Connect/ConnectUser.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Connect
|
||||
{
|
||||
public class ConnectUser
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Email { get; set; }
|
||||
}
|
||||
|
||||
public class ConnectUserQuery
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Email { get; set; }
|
||||
}
|
||||
}
|
10
MediaBrowser.Controller/Connect/ConnectUserLink.cs
Normal file
10
MediaBrowser.Controller/Connect/ConnectUserLink.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
namespace MediaBrowser.Controller.Connect
|
||||
{
|
||||
public class ConnectUserLink
|
||||
{
|
||||
public string Username { get; set; }
|
||||
public string UserId { get; set; }
|
||||
public string LocalUserId { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,8 +1,35 @@
|
|||
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Connect
|
||||
{
|
||||
public interface IConnectManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the wan API address.
|
||||
/// </summary>
|
||||
/// <value>The wan API address.</value>
|
||||
string WanApiAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user information.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user identifier.</param>
|
||||
/// <returns>ConnectUserInfo.</returns>
|
||||
ConnectUserLink GetUserInfo(string userId);
|
||||
|
||||
/// <summary>
|
||||
/// Links the user.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user identifier.</param>
|
||||
/// <param name="connectUsername">The connect username.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task LinkUser(string userId, string connectUsername);
|
||||
|
||||
/// <summary>
|
||||
/// Removes the link.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user identifier.</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task RemoveLink(string userId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,12 @@ namespace MediaBrowser.Controller.Entities
|
|||
public static IUserManager UserManager { get; set; }
|
||||
public static IXmlSerializer XmlSerializer { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// From now on all user paths will be Id-based.
|
||||
/// This is for backwards compatibility.
|
||||
/// </summary>
|
||||
public bool UsesIdForConfigurationPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password.
|
||||
/// </summary>
|
||||
|
@ -26,6 +32,10 @@ namespace MediaBrowser.Controller.Entities
|
|||
public string Password { get; set; }
|
||||
public string LocalPassword { get; set; }
|
||||
|
||||
public string ConnectUserName { get; set; }
|
||||
public string ConnectUserId { get; set; }
|
||||
public string ConnectAccessKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the path.
|
||||
/// </summary>
|
||||
|
@ -136,12 +146,14 @@ namespace MediaBrowser.Controller.Entities
|
|||
{
|
||||
if (string.IsNullOrEmpty(newName))
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
throw new ArgumentNullException("newName");
|
||||
}
|
||||
|
||||
// If only the casing is changing, leave the file system alone
|
||||
if (!newName.Equals(Name, StringComparison.OrdinalIgnoreCase))
|
||||
if (!UsesIdForConfigurationPath && !newName.Equals(Name, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
UsesIdForConfigurationPath = true;
|
||||
|
||||
// Move configuration
|
||||
var newConfigDirectory = GetConfigurationDirectoryPath(newName);
|
||||
var oldConfigurationDirectory = ConfigurationDirectoryPath;
|
||||
|
@ -168,7 +180,8 @@ namespace MediaBrowser.Controller.Entities
|
|||
{
|
||||
ReplaceAllMetadata = true,
|
||||
ImageRefreshMode = ImageRefreshMode.FullRefresh,
|
||||
MetadataRefreshMode = MetadataRefreshMode.FullRefresh
|
||||
MetadataRefreshMode = MetadataRefreshMode.FullRefresh,
|
||||
ForceSave = true
|
||||
|
||||
}, CancellationToken.None);
|
||||
}
|
||||
|
@ -183,7 +196,7 @@ namespace MediaBrowser.Controller.Entities
|
|||
/// </summary>
|
||||
/// <value>The configuration directory path.</value>
|
||||
[IgnoreDataMember]
|
||||
public string ConfigurationDirectoryPath
|
||||
private string ConfigurationDirectoryPath
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -203,9 +216,17 @@ namespace MediaBrowser.Controller.Entities
|
|||
throw new ArgumentNullException("username");
|
||||
}
|
||||
|
||||
var safeFolderName = FileSystem.GetValidFilename(username);
|
||||
var parentPath = ConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath;
|
||||
|
||||
return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath, safeFolderName);
|
||||
// Legacy
|
||||
if (!UsesIdForConfigurationPath)
|
||||
{
|
||||
var safeFolderName = FileSystem.GetValidFilename(username);
|
||||
|
||||
return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath, safeFolderName);
|
||||
}
|
||||
|
||||
return System.IO.Path.Combine(parentPath, Id.ToString("N"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -49,6 +49,13 @@ namespace MediaBrowser.Controller.Library
|
|||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
User GetUserById(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user by identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>User.</returns>
|
||||
User GetUserById(string id);
|
||||
|
||||
/// <summary>
|
||||
/// Authenticates a User and returns a result indicating whether or not it succeeded
|
||||
/// </summary>
|
||||
|
|
|
@ -99,6 +99,9 @@
|
|||
<Compile Include="Collections\CollectionCreationOptions.cs" />
|
||||
<Compile Include="Collections\CollectionEvents.cs" />
|
||||
<Compile Include="Collections\ICollectionManager.cs" />
|
||||
<Compile Include="Connect\ConnectInvitationRequest.cs" />
|
||||
<Compile Include="Connect\ConnectUser.cs" />
|
||||
<Compile Include="Connect\ConnectUserLink.cs" />
|
||||
<Compile Include="Connect\IConnectManager.cs" />
|
||||
<Compile Include="Dlna\ControlRequest.cs" />
|
||||
<Compile Include="Dlna\ControlResponse.cs" />
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace MediaBrowser.Controller.Net
|
|||
{
|
||||
var userId = auth.UserId;
|
||||
|
||||
user = UserManager.GetUserById(new Guid(userId));
|
||||
user = UserManager.GetUserById(userId);
|
||||
}
|
||||
|
||||
string deviceId = auth.DeviceId;
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
|||
{
|
||||
if (!string.IsNullOrEmpty(profile.UserId))
|
||||
{
|
||||
var user = _userManager.GetUserById(new Guid(profile.UserId));
|
||||
var user = _userManager.GetUserById(profile.UserId);
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
|
@ -93,7 +93,7 @@ namespace MediaBrowser.Dlna.ContentDirectory
|
|||
|
||||
if (!string.IsNullOrEmpty(userId))
|
||||
{
|
||||
var user = _userManager.GetUserById(new Guid(userId));
|
||||
var user = _userManager.GetUserById(userId);
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
|
|
|
@ -281,7 +281,7 @@ namespace MediaBrowser.Dlna.PlayTo
|
|||
{
|
||||
_logger.Debug("{0} - Received PlayRequest: {1}", this._session.DeviceName, command.PlayCommand);
|
||||
|
||||
var user = String.IsNullOrEmpty(command.ControllingUserId) ? null : _userManager.GetUserById(new Guid(command.ControllingUserId));
|
||||
var user = String.IsNullOrEmpty(command.ControllingUserId) ? null : _userManager.GetUserById(command.ControllingUserId);
|
||||
|
||||
var items = new List<BaseItem>();
|
||||
foreach (string id in command.ItemIds)
|
||||
|
|
|
@ -78,14 +78,15 @@ namespace MediaBrowser.Model.Configuration
|
|||
public bool EnableLocalPassword { get; set; }
|
||||
|
||||
public string[] OrderedViews { get; set; }
|
||||
|
||||
|
||||
public bool SyncConnectName { get; set; }
|
||||
public bool SyncConnectImage { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UserConfiguration" /> class.
|
||||
/// </summary>
|
||||
public UserConfiguration()
|
||||
{
|
||||
IsAdministrator = true;
|
||||
|
||||
PlayDefaultAudioTrack = true;
|
||||
EnableRemoteControlOfOtherUsers = true;
|
||||
EnableLiveTvManagement = true;
|
||||
|
@ -101,6 +102,9 @@ namespace MediaBrowser.Model.Configuration
|
|||
ExcludeFoldersFromGrouping = new string[] { };
|
||||
DisplayCollectionsView = true;
|
||||
DisplayFoldersView = true;
|
||||
|
||||
SyncConnectName = true;
|
||||
SyncConnectImage = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||
{
|
||||
var user = string.IsNullOrWhiteSpace(query.UserId)
|
||||
? null
|
||||
: _userManager.GetUserById(new Guid(query.UserId));
|
||||
: _userManager.GetUserById(query.UserId);
|
||||
|
||||
var channels = GetAllChannels()
|
||||
.Select(GetChannelEntity)
|
||||
|
@ -163,7 +163,7 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||
{
|
||||
var user = string.IsNullOrWhiteSpace(query.UserId)
|
||||
? null
|
||||
: _userManager.GetUserById(new Guid(query.UserId));
|
||||
: _userManager.GetUserById(query.UserId);
|
||||
|
||||
var internalResult = await GetChannelsInternal(query, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
|
@ -565,7 +565,7 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||
{
|
||||
var user = string.IsNullOrWhiteSpace(query.UserId)
|
||||
? null
|
||||
: _userManager.GetUserById(new Guid(query.UserId));
|
||||
: _userManager.GetUserById(query.UserId);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(query.UserId) && user == null)
|
||||
{
|
||||
|
@ -724,7 +724,7 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||
{
|
||||
var user = string.IsNullOrWhiteSpace(query.UserId)
|
||||
? null
|
||||
: _userManager.GetUserById(new Guid(query.UserId));
|
||||
: _userManager.GetUserById(query.UserId);
|
||||
|
||||
var channels = GetAllChannels();
|
||||
|
||||
|
@ -897,7 +897,7 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||
|
||||
var user = string.IsNullOrWhiteSpace(query.UserId)
|
||||
? null
|
||||
: _userManager.GetUserById(new Guid(query.UserId));
|
||||
: _userManager.GetUserById(query.UserId);
|
||||
|
||||
ChannelItemSortField? sortField = null;
|
||||
ChannelItemSortField parsedField;
|
||||
|
@ -942,7 +942,7 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||
{
|
||||
var user = string.IsNullOrWhiteSpace(query.UserId)
|
||||
? null
|
||||
: _userManager.GetUserById(new Guid(query.UserId));
|
||||
: _userManager.GetUserById(query.UserId);
|
||||
|
||||
var internalResult = await GetChannelItemsInternal(query, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
|
@ -1356,7 +1356,7 @@ namespace MediaBrowser.Server.Implementations.Channels
|
|||
|
||||
public async Task<BaseItemDto> GetChannelFolder(string userId, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = string.IsNullOrEmpty(userId) ? null : _userManager.GetUserById(new Guid(userId));
|
||||
var user = string.IsNullOrEmpty(userId) ? null : _userManager.GetUserById(userId);
|
||||
|
||||
// Get everything
|
||||
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Connect
|
||||
{
|
||||
public class ConnectData
|
||||
|
@ -13,5 +15,27 @@ namespace MediaBrowser.Server.Implementations.Connect
|
|||
/// </summary>
|
||||
/// <value>The access key.</value>
|
||||
public string AccessKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the authorizations.
|
||||
/// </summary>
|
||||
/// <value>The authorizations.</value>
|
||||
public List<ConnectAuthorization> Authorizations { get; set; }
|
||||
|
||||
public ConnectData()
|
||||
{
|
||||
Authorizations = new List<ConnectAuthorization>();
|
||||
}
|
||||
}
|
||||
|
||||
public class ConnectAuthorization
|
||||
{
|
||||
public string LocalUserId { get; set; }
|
||||
public string AccessToken { get; set; }
|
||||
|
||||
public ConnectAuthorization()
|
||||
{
|
||||
AccessToken = new Guid().ToString("N");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ using MediaBrowser.Common.Net;
|
|||
using MediaBrowser.Controller;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Connect;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Controller.Security;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.Net;
|
||||
|
@ -27,9 +29,18 @@ namespace MediaBrowser.Server.Implementations.Connect
|
|||
private readonly IHttpClient _httpClient;
|
||||
private readonly IServerApplicationHost _appHost;
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
public string ConnectServerId { get; set; }
|
||||
public string ConnectAccessKey { get; set; }
|
||||
private ConnectData _data = new ConnectData();
|
||||
|
||||
public string ConnectServerId
|
||||
{
|
||||
get { return _data.ServerId; }
|
||||
}
|
||||
public string ConnectAccessKey
|
||||
{
|
||||
get { return _data.AccessKey; }
|
||||
}
|
||||
|
||||
public string DiscoveredWanIpAddress { get; private set; }
|
||||
|
||||
|
@ -47,7 +58,7 @@ namespace MediaBrowser.Server.Implementations.Connect
|
|||
return address;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string WanApiAddress
|
||||
{
|
||||
get
|
||||
|
@ -75,7 +86,7 @@ namespace MediaBrowser.Server.Implementations.Connect
|
|||
IEncryptionManager encryption,
|
||||
IHttpClient httpClient,
|
||||
IServerApplicationHost appHost,
|
||||
IServerConfigurationManager config)
|
||||
IServerConfigurationManager config, IUserManager userManager)
|
||||
{
|
||||
_logger = logger;
|
||||
_appPaths = appPaths;
|
||||
|
@ -84,6 +95,7 @@ namespace MediaBrowser.Server.Implementations.Connect
|
|||
_httpClient = httpClient;
|
||||
_appHost = appHost;
|
||||
_config = config;
|
||||
_userManager = userManager;
|
||||
|
||||
LoadCachedData();
|
||||
}
|
||||
|
@ -156,8 +168,8 @@ namespace MediaBrowser.Server.Implementations.Connect
|
|||
{
|
||||
var data = _json.DeserializeFromStream<ServerRegistrationResponse>(stream);
|
||||
|
||||
ConnectServerId = data.Id;
|
||||
ConnectAccessKey = data.AccessKey;
|
||||
_data.ServerId = data.Id;
|
||||
_data.AccessKey = data.AccessKey;
|
||||
|
||||
CacheData();
|
||||
}
|
||||
|
@ -182,7 +194,7 @@ namespace MediaBrowser.Server.Implementations.Connect
|
|||
{"systemid", _appHost.SystemId}
|
||||
});
|
||||
|
||||
options.RequestHeaders.Add("X-Connect-Token", ConnectAccessKey);
|
||||
SetServerAccessToken(options);
|
||||
|
||||
// No need to examine the response
|
||||
using (var stream = (await _httpClient.Post(options).ConfigureAwait(false)).Content)
|
||||
|
@ -203,11 +215,7 @@ namespace MediaBrowser.Server.Implementations.Connect
|
|||
{
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(path));
|
||||
|
||||
var json = _json.SerializeToString(new ConnectData
|
||||
{
|
||||
AccessKey = ConnectAccessKey,
|
||||
ServerId = ConnectServerId
|
||||
});
|
||||
var json = _json.SerializeToString(_data);
|
||||
|
||||
var encrypted = _encryption.EncryptString(json);
|
||||
|
||||
|
@ -229,10 +237,7 @@ namespace MediaBrowser.Server.Implementations.Connect
|
|||
|
||||
var json = _encryption.DecryptString(encrypted);
|
||||
|
||||
var data = _json.DeserializeFromString<ConnectData>(json);
|
||||
|
||||
ConnectAccessKey = data.AccessKey;
|
||||
ConnectServerId = data.ServerId;
|
||||
_data = _json.DeserializeFromString<ConnectData>(json);
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
|
@ -244,9 +249,181 @@ namespace MediaBrowser.Server.Implementations.Connect
|
|||
}
|
||||
}
|
||||
|
||||
private User GetUser(string id)
|
||||
{
|
||||
var user = _userManager.GetUserById(id);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentException("User not found.");
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
public ConnectUserLink GetUserInfo(string userId)
|
||||
{
|
||||
var user = GetUser(userId);
|
||||
|
||||
return new ConnectUserLink
|
||||
{
|
||||
LocalUserId = user.Id.ToString("N"),
|
||||
Username = user.ConnectUserName,
|
||||
UserId = user.ConnectUserId
|
||||
};
|
||||
}
|
||||
|
||||
private string GetConnectUrl(string handler)
|
||||
{
|
||||
return "http://mb3admin.com/test/connect/" + handler;
|
||||
}
|
||||
|
||||
public async Task LinkUser(string userId, string connectUsername)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(connectUsername))
|
||||
{
|
||||
throw new ArgumentNullException("connectUsername");
|
||||
}
|
||||
|
||||
var connectUser = await GetConnectUser(new ConnectUserQuery
|
||||
{
|
||||
Name = connectUsername
|
||||
|
||||
}, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
var user = GetUser(userId);
|
||||
|
||||
// See if it's already been set.
|
||||
if (string.Equals(connectUser.Id, user.ConnectUserId, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(user.ConnectUserId))
|
||||
{
|
||||
await RemoveLink(user, connectUser).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
var url = GetConnectUrl("ServerAuthorizations");
|
||||
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = CancellationToken.None
|
||||
};
|
||||
|
||||
var accessToken = Guid.NewGuid().ToString("N");
|
||||
|
||||
var postData = new Dictionary<string, string>
|
||||
{
|
||||
{"serverId", ConnectServerId},
|
||||
{"userId", connectUser.Id},
|
||||
{"userType", "Linked"},
|
||||
{"accessToken", accessToken}
|
||||
};
|
||||
|
||||
options.SetPostData(postData);
|
||||
|
||||
SetServerAccessToken(options);
|
||||
|
||||
// No need to examine the response
|
||||
using (var stream = (await _httpClient.Post(options).ConfigureAwait(false)).Content)
|
||||
{
|
||||
}
|
||||
|
||||
user.ConnectAccessKey = accessToken;
|
||||
user.ConnectUserName = connectUser.Name;
|
||||
user.ConnectUserId = connectUser.Id;
|
||||
|
||||
await user.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task RemoveLink(string userId)
|
||||
{
|
||||
var user = GetUser(userId);
|
||||
|
||||
var connectUser = await GetConnectUser(new ConnectUserQuery
|
||||
{
|
||||
Name = user.ConnectUserId
|
||||
|
||||
}, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
await RemoveLink(user, connectUser).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task RemoveLink(User user, ConnectUser connectUser)
|
||||
{
|
||||
var url = GetConnectUrl("ServerAuthorizations");
|
||||
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = CancellationToken.None
|
||||
};
|
||||
|
||||
var postData = new Dictionary<string, string>
|
||||
{
|
||||
{"serverId", ConnectServerId},
|
||||
{"userId", connectUser.Id}
|
||||
};
|
||||
|
||||
options.SetPostData(postData);
|
||||
|
||||
SetServerAccessToken(options);
|
||||
|
||||
// No need to examine the response
|
||||
using (var stream = (await _httpClient.SendAsync(options, "DELETE").ConfigureAwait(false)).Content)
|
||||
{
|
||||
}
|
||||
|
||||
user.ConnectAccessKey = null;
|
||||
user.ConnectUserName = null;
|
||||
user.ConnectUserId = null;
|
||||
|
||||
await user.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task<ConnectUser> GetConnectUser(ConnectUserQuery query, CancellationToken cancellationToken)
|
||||
{
|
||||
var url = GetConnectUrl("user");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(query.Id))
|
||||
{
|
||||
url = url + "?id=" + WebUtility.UrlEncode(query.Id);
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(query.Name))
|
||||
{
|
||||
url = url + "?name=" + WebUtility.UrlEncode(query.Name);
|
||||
}
|
||||
else if (!string.IsNullOrWhiteSpace(query.Email))
|
||||
{
|
||||
url = url + "?email=" + WebUtility.UrlEncode(query.Email);
|
||||
}
|
||||
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
CancellationToken = cancellationToken,
|
||||
Url = url
|
||||
};
|
||||
|
||||
SetServerAccessToken(options);
|
||||
|
||||
using (var stream = await _httpClient.Get(options).ConfigureAwait(false))
|
||||
{
|
||||
var response = _json.DeserializeFromStream<GetConnectUserResponse>(stream);
|
||||
|
||||
return new ConnectUser
|
||||
{
|
||||
Email = response.Email,
|
||||
Id = response.Id,
|
||||
Name = response.Name
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void SetServerAccessToken(HttpRequestOptions options)
|
||||
{
|
||||
options.RequestHeaders.Add("X-Connect-Token", ConnectAccessKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,4 +15,14 @@ namespace MediaBrowser.Server.Implementations.Connect
|
|||
public string Url { get; set; }
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
public class GetConnectUserResponse
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public string Email { get; set; }
|
||||
public string IsActive { get; set; }
|
||||
public string ImageUrl { get; set; }
|
||||
}
|
||||
}
|
|
@ -69,7 +69,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
|
|||
|
||||
var user = string.IsNullOrWhiteSpace(auth.UserId)
|
||||
? null
|
||||
: UserManager.GetUserById(new Guid(auth.UserId));
|
||||
: UserManager.GetUserById(auth.UserId);
|
||||
|
||||
if (user == null & !string.IsNullOrWhiteSpace(auth.UserId))
|
||||
{
|
||||
|
|
|
@ -39,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
}
|
||||
else
|
||||
{
|
||||
var user = _userManager.GetUserById(new Guid(query.UserId));
|
||||
var user = _userManager.GetUserById(query.UserId);
|
||||
|
||||
inputItems = user.RootFolder.GetRecursiveChildren(user, true);
|
||||
}
|
||||
|
|
|
@ -128,6 +128,16 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
return Users.FirstOrDefault(u => u.Id == id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user by identifier.
|
||||
/// </summary>
|
||||
/// <param name="id">The identifier.</param>
|
||||
/// <returns>User.</returns>
|
||||
public User GetUserById(string id)
|
||||
{
|
||||
return GetUserById(new Guid(id));
|
||||
}
|
||||
|
||||
public async Task Initialize()
|
||||
{
|
||||
Users = await LoadUsers().ConfigureAwait(false);
|
||||
|
@ -219,6 +229,9 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
users.Add(user);
|
||||
|
||||
user.Configuration.IsAdministrator = true;
|
||||
UpdateConfiguration(user, user.Configuration);
|
||||
}
|
||||
|
||||
return users;
|
||||
|
@ -503,7 +516,8 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
Name = name,
|
||||
Id = ("MBUser" + name).GetMD5(),
|
||||
DateCreated = DateTime.UtcNow,
|
||||
DateModified = DateTime.UtcNow
|
||||
DateModified = DateTime.UtcNow,
|
||||
UsesIdForConfigurationPath = true
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ namespace MediaBrowser.Server.Implementations.Library
|
|||
|
||||
public async Task<IEnumerable<Folder>> GetUserViews(UserViewQuery query, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = _userManager.GetUserById(new Guid(query.UserId));
|
||||
var user = _userManager.GetUserById(query.UserId);
|
||||
|
||||
var folders = user.RootFolder
|
||||
.GetChildren(user, true)
|
||||
|
|
|
@ -133,7 +133,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
|
||||
public async Task<QueryResult<LiveTvChannel>> GetInternalChannels(LiveTvChannelQuery query, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId));
|
||||
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
|
||||
|
||||
var channels = _channelIdList.Select(_libraryManager.GetItemById)
|
||||
.Where(i => i != null)
|
||||
|
@ -231,7 +231,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
|
||||
public async Task<QueryResult<ChannelInfoDto>> GetChannels(LiveTvChannelQuery query, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId));
|
||||
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
|
||||
|
||||
var internalResult = await GetInternalChannels(query, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
|
@ -693,7 +693,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
});
|
||||
}
|
||||
|
||||
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId));
|
||||
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
|
||||
|
||||
if (user != null)
|
||||
{
|
||||
|
@ -730,7 +730,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
{
|
||||
IEnumerable<LiveTvProgram> programs = _programs.Values;
|
||||
|
||||
var user = _userManager.GetUserById(new Guid(query.UserId));
|
||||
var user = _userManager.GetUserById(query.UserId);
|
||||
|
||||
// Avoid implicitly captured closure
|
||||
var currentUser = user;
|
||||
|
@ -786,7 +786,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
{
|
||||
var internalResult = await GetRecommendedProgramsInternal(query, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
var user = _userManager.GetUserById(new Guid(query.UserId));
|
||||
var user = _userManager.GetUserById(query.UserId);
|
||||
|
||||
var returnArray = internalResult.Items
|
||||
.Select(i =>
|
||||
|
@ -1099,7 +1099,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
};
|
||||
}
|
||||
|
||||
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId));
|
||||
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
|
||||
|
||||
var recordings = await service.GetRecordingsAsync(cancellationToken).ConfigureAwait(false);
|
||||
|
||||
|
@ -1199,7 +1199,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
};
|
||||
}
|
||||
|
||||
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(new Guid(query.UserId));
|
||||
var user = string.IsNullOrEmpty(query.UserId) ? null : _userManager.GetUserById(query.UserId);
|
||||
|
||||
var internalResult = await GetInternalRecordings(query, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
|
@ -1869,7 +1869,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
|||
|
||||
public async Task<BaseItemDto> GetLiveTvFolder(string userId, CancellationToken cancellationToken)
|
||||
{
|
||||
var user = string.IsNullOrEmpty(userId) ? null : _userManager.GetUserById(new Guid(userId));
|
||||
var user = string.IsNullOrEmpty(userId) ? null : _userManager.GetUserById(userId);
|
||||
|
||||
// Get everything
|
||||
var fields = Enum.GetNames(typeof(ItemFields)).Select(i => (ItemFields)Enum.Parse(typeof(ItemFields), i, true)).ToList();
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"FileNotFound": "File not found.",
|
||||
"FileReadError": "An error occurred while reading the file.",
|
||||
"DeleteUser": "Delete User",
|
||||
"DeleteUserConfirmation": "Are you sure you wish to delete {0}?",
|
||||
"DeleteUserConfirmation": "Are you sure you wish to delete this user?",
|
||||
"PasswordResetHeader": "Password Reset",
|
||||
"PasswordResetComplete": "The password has been reset.",
|
||||
"PasswordResetConfirmation": "Are you sure you wish to reset the password?",
|
||||
|
@ -450,5 +450,8 @@
|
|||
"MessageChangeRecurringPlanConfirm": "After completing this transaction you will need to cancel your previous recurring donation from within your PayPal account. Thank you for supporting Media Browser.",
|
||||
"MessageSupporterMembershipExpiredOn": "Your supporter membership expired on {0}.",
|
||||
"MessageYouHaveALifetimeMembership": "You have a lifetime supporter membership. You can provide additional donations on a one-time or recurring basis using the options below. Thank you for supporting Media Browser.",
|
||||
"MessageYouHaveAnActiveRecurringMembership": "You have an active {0} membership. You can upgrade your plan using the options below."
|
||||
"MessageYouHaveAnActiveRecurringMembership": "You have an active {0} membership. You can upgrade your plan using the options below.",
|
||||
"ButtonDelete": "Delete",
|
||||
"HeaderMediaBrowserAccountAdded": "Media Browser Account Added",
|
||||
"MessageMediaBrowserAccontAdded": "A Media Browser account has been added to this user. An email has been sent to the owner of the account. They will need to confirm the invitation by clicking a link within the email."
|
||||
}
|
||||
|
|
|
@ -74,6 +74,8 @@
|
|||
"TabProfiles": "Profiles",
|
||||
"TabSecurity": "Security",
|
||||
"ButtonAddUser": "Add User",
|
||||
"ButtonAddLocalUser": "Add Local User",
|
||||
"ButtonInviteMediaBrowserUser": "Invite Media Browser User",
|
||||
"ButtonSave": "Save",
|
||||
"ButtonResetPassword": "Reset Password",
|
||||
"LabelNewPassword": "New password:",
|
||||
|
@ -1156,5 +1158,7 @@
|
|||
"XmlDocumentAttributeListHelp": "These attributes are applied to the root element of every xml response.",
|
||||
"OptionSaveMetadataAsHidden": "Save metadata and images as hidden files",
|
||||
"LabelExtractChaptersDuringLibraryScan": "Extract chapter images during the library scan",
|
||||
"LabelExtractChaptersDuringLibraryScanHelp": "If enabled, chapter images will be extracted when videos are imported during the library scan. If disabled they will be extracted during the chapter images scheduled task, allowing the regular library scan to complete faster."
|
||||
"LabelExtractChaptersDuringLibraryScanHelp": "If enabled, chapter images will be extracted when videos are imported during the library scan. If disabled they will be extracted during the chapter images scheduled task, allowing the regular library scan to complete faster.",
|
||||
"LabelConnectUserName": "Media Browser username/email:",
|
||||
"LabelConnectUserNameHelp": "Connect this user to a Media Browser account to enable easy sign-in access from any app without having to know the server ip address."
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@
|
|||
<Compile Include="Configuration\ServerConfigurationManager.cs" />
|
||||
<Compile Include="Connect\ConnectData.cs" />
|
||||
<Compile Include="Connect\ConnectManager.cs" />
|
||||
<Compile Include="Connect\ServerRegistrationResponse.cs" />
|
||||
<Compile Include="Connect\Responses.cs" />
|
||||
<Compile Include="Drawing\ImageHeader.cs" />
|
||||
<Compile Include="Drawing\PercentPlayedDrawer.cs" />
|
||||
<Compile Include="Drawing\PlayedIndicatorDrawer.cs" />
|
||||
|
|
|
@ -44,7 +44,7 @@ namespace MediaBrowser.Server.Implementations.Notifications
|
|||
GetConfiguration().GetOptions(notificationType);
|
||||
|
||||
var users = GetUserIds(request, options)
|
||||
.Select(i => _userManager.GetUserById(new Guid(i)));
|
||||
.Select(i => _userManager.GetUserById(i));
|
||||
|
||||
var title = GetTitle(request, options);
|
||||
var description = GetDescription(request, options);
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace MediaBrowser.Server.Implementations.Playlists
|
|||
|
||||
public IEnumerable<Playlist> GetPlaylists(string userId)
|
||||
{
|
||||
var user = _userManager.GetUserById(new Guid(userId));
|
||||
var user = _userManager.GetUserById(userId);
|
||||
|
||||
return GetPlaylistsFolder(userId).GetChildren(user, true).OfType<Playlist>();
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ namespace MediaBrowser.Server.Implementations.Playlists
|
|||
throw new ArgumentException("A playlist media type is required.");
|
||||
}
|
||||
|
||||
var user = _userManager.GetUserById(new Guid(options.UserId));
|
||||
var user = _userManager.GetUserById(options.UserId);
|
||||
|
||||
var path = Path.Combine(parentFolder.Path, folderName);
|
||||
path = GetTargetPath(path);
|
||||
|
@ -162,7 +162,7 @@ namespace MediaBrowser.Server.Implementations.Playlists
|
|||
|
||||
public Task AddToPlaylist(string playlistId, IEnumerable<string> itemIds, string userId)
|
||||
{
|
||||
var user = string.IsNullOrWhiteSpace(userId) ? null : _userManager.GetUserById(new Guid(userId));
|
||||
var user = string.IsNullOrWhiteSpace(userId) ? null : _userManager.GetUserById(userId);
|
||||
|
||||
return AddToPlaylistInternal(playlistId, itemIds, user);
|
||||
}
|
||||
|
|
|
@ -455,7 +455,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
users.Add(user);
|
||||
|
||||
var additionalUsers = session.AdditionalUsers
|
||||
.Select(i => _userManager.GetUserById(new Guid(i.UserId)))
|
||||
.Select(i => _userManager.GetUserById(i.UserId))
|
||||
.Where(i => i != null);
|
||||
|
||||
users.AddRange(additionalUsers);
|
||||
|
@ -1189,7 +1189,7 @@ namespace MediaBrowser.Server.Implementations.Session
|
|||
|
||||
if (!string.IsNullOrWhiteSpace(info.UserId))
|
||||
{
|
||||
var user = _userManager.GetUserById(new Guid(info.UserId));
|
||||
var user = _userManager.GetUserById(info.UserId);
|
||||
|
||||
if (user == null || user.Configuration.IsDisabled)
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@ namespace MediaBrowser.Server.Implementations.TV
|
|||
|
||||
public QueryResult<BaseItem> GetNextUp(NextUpQuery request)
|
||||
{
|
||||
var user = _userManager.GetUserById(new Guid(request.UserId));
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ namespace MediaBrowser.Server.Implementations.TV
|
|||
|
||||
public QueryResult<BaseItem> GetNextUp(NextUpQuery request, IEnumerable<Folder> parentsFolders)
|
||||
{
|
||||
var user = _userManager.GetUserById(new Guid(request.UserId));
|
||||
var user = _userManager.GetUserById(request.UserId);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
|
|
|
@ -5,6 +5,7 @@ using MediaBrowser.Model.Logging;
|
|||
using MediaBrowser.Server.Implementations;
|
||||
using MediaBrowser.ServerApplication;
|
||||
using MediaBrowser.ServerApplication.Native;
|
||||
using MediaBrowser.ServerApplication.IO;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
|
@ -41,8 +42,10 @@ namespace MediaBrowser.Server.Mono
|
|||
var applicationPath = Assembly.GetEntryAssembly ().Location;
|
||||
#endif
|
||||
|
||||
var options = new StartupOptions();
|
||||
|
||||
// Allow this to be specified on the command line.
|
||||
var customProgramDataPath = ParseProgramDataPathFromCommandLine();
|
||||
var customProgramDataPath = options.GetOption("-programdata");
|
||||
|
||||
var appPaths = CreateApplicationPaths(applicationPath, customProgramDataPath);
|
||||
|
||||
|
@ -52,7 +55,7 @@ namespace MediaBrowser.Server.Mono
|
|||
|
||||
var logger = _logger = logManager.GetLogger("Main");
|
||||
|
||||
BeginLog(logger);
|
||||
BeginLog(logger, appPaths);
|
||||
|
||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||
|
||||
|
@ -64,7 +67,7 @@ namespace MediaBrowser.Server.Mono
|
|||
|
||||
try
|
||||
{
|
||||
RunApplication(appPaths, logManager);
|
||||
RunApplication(appPaths, logManager, options);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -73,20 +76,6 @@ namespace MediaBrowser.Server.Mono
|
|||
_appHost.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private static string ParseProgramDataPathFromCommandLine()
|
||||
{
|
||||
var commandArgs = Environment.GetCommandLineArgs().ToList();
|
||||
|
||||
var programDataPathIndex = commandArgs.IndexOf("-programdata");
|
||||
|
||||
if (programDataPathIndex != -1)
|
||||
{
|
||||
return commandArgs.ElementAtOrDefault(programDataPathIndex + 1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static ServerApplicationPaths CreateApplicationPaths(string applicationPath, string programDataPath)
|
||||
{
|
||||
|
@ -126,14 +115,14 @@ namespace MediaBrowser.Server.Mono
|
|||
|
||||
private static TaskCompletionSource<bool> _applicationTaskCompletionSource = new TaskCompletionSource<bool>();
|
||||
|
||||
private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager)
|
||||
private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, StartupOptions options)
|
||||
{
|
||||
SystemEvents.SessionEnding += SystemEvents_SessionEnding;
|
||||
|
||||
// Allow all https requests
|
||||
ServicePointManager.ServerCertificateValidationCallback = _ignoreCertificates;
|
||||
|
||||
_appHost = new ApplicationHost(appPaths, logManager, false, false);
|
||||
_appHost = new ApplicationHost(appPaths, logManager, false, false, options);
|
||||
|
||||
Console.WriteLine ("appHost.Init");
|
||||
|
||||
|
@ -169,14 +158,11 @@ namespace MediaBrowser.Server.Mono
|
|||
/// Begins the log.
|
||||
/// </summary>
|
||||
/// <param name="logger">The logger.</param>
|
||||
private static void BeginLog(ILogger logger)
|
||||
{
|
||||
logger.Info("Media Browser Server started");
|
||||
logger.Info("Command line: {0}", string.Join(" ", Environment.GetCommandLineArgs()));
|
||||
|
||||
logger.Info("Server: {0}", Environment.MachineName);
|
||||
logger.Info("Operating system: {0}", Environment.OSVersion.ToString());
|
||||
}
|
||||
private static void BeginLog(ILogger logger, IApplicationPaths appPaths)
|
||||
{
|
||||
logger.Info("Media Browser Server started");
|
||||
ApplicationHost.LogEnvironmentInfo(logger, appPaths);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles the UnhandledException event of the CurrentDomain control.
|
||||
|
|
|
@ -219,6 +219,8 @@ namespace MediaBrowser.ServerApplication
|
|||
private ISyncRepository SyncRepository { get; set; }
|
||||
private ITVSeriesManager TVSeriesManager { get; set; }
|
||||
|
||||
private StartupOptions _startupOptions;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ApplicationHost" /> class.
|
||||
/// </summary>
|
||||
|
@ -226,9 +228,15 @@ namespace MediaBrowser.ServerApplication
|
|||
/// <param name="logManager">The log manager.</param>
|
||||
/// <param name="supportsRunningAsService">if set to <c>true</c> [supports running as service].</param>
|
||||
/// <param name="isRunningAsService">if set to <c>true</c> [is running as service].</param>
|
||||
public ApplicationHost(ServerApplicationPaths applicationPaths, ILogManager logManager, bool supportsRunningAsService, bool isRunningAsService)
|
||||
/// <param name="options">The options.</param>
|
||||
public ApplicationHost(ServerApplicationPaths applicationPaths,
|
||||
ILogManager logManager,
|
||||
bool supportsRunningAsService,
|
||||
bool isRunningAsService,
|
||||
StartupOptions options)
|
||||
: base(applicationPaths, logManager)
|
||||
{
|
||||
_startupOptions = options;
|
||||
_isRunningAsService = isRunningAsService;
|
||||
SupportsRunningAsService = supportsRunningAsService;
|
||||
}
|
||||
|
@ -447,7 +455,7 @@ namespace MediaBrowser.ServerApplication
|
|||
var encryptionManager = new EncryptionManager();
|
||||
RegisterSingleInstance<IEncryptionManager>(encryptionManager);
|
||||
|
||||
ConnectManager = new ConnectManager(LogManager.GetLogger("Connect"), ApplicationPaths, JsonSerializer, encryptionManager, HttpClient, this, ServerConfigurationManager);
|
||||
ConnectManager = new ConnectManager(LogManager.GetLogger("Connect"), ApplicationPaths, JsonSerializer, encryptionManager, HttpClient, this, ServerConfigurationManager, UserManager);
|
||||
RegisterSingleInstance(ConnectManager);
|
||||
|
||||
SessionManager = new SessionManager(UserDataManager, ServerConfigurationManager, Logger, UserRepository, LibraryManager, UserManager, musicManager, DtoService, ImageProcessor, ItemRepository, JsonSerializer, this, HttpClient, AuthenticationRepository);
|
||||
|
@ -548,7 +556,7 @@ namespace MediaBrowser.ServerApplication
|
|||
/// <returns>Task.</returns>
|
||||
private async Task RegisterMediaEncoder(IProgress<double> progress)
|
||||
{
|
||||
var info = await new FFMpegDownloader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager).GetFFMpegInfo(progress).ConfigureAwait(false);
|
||||
var info = await new FFMpegDownloader(Logger, ApplicationPaths, HttpClient, ZipClient, FileSystemManager).GetFFMpegInfo(_startupOptions, progress).ConfigureAwait(false);
|
||||
|
||||
MediaEncoder = new MediaEncoder(LogManager.GetLogger("MediaEncoder"), JsonSerializer, info.EncoderPath, info.ProbePath, info.Version);
|
||||
RegisterSingleInstance(MediaEncoder);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using MediaBrowser.Common.Configuration;
|
||||
using System.Collections.Generic;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Model.IO;
|
||||
|
@ -13,6 +14,7 @@ using System.Threading.Tasks;
|
|||
#if __MonoCS__
|
||||
using Mono.Unix.Native;
|
||||
#endif
|
||||
using MediaBrowser.ServerApplication.IO;
|
||||
|
||||
namespace MediaBrowser.ServerApplication.FFMpeg
|
||||
{
|
||||
|
@ -38,8 +40,21 @@ namespace MediaBrowser.ServerApplication.FFMpeg
|
|||
_fileSystem = fileSystem;
|
||||
}
|
||||
|
||||
public async Task<FFMpegInfo> GetFFMpegInfo(IProgress<double> progress)
|
||||
public async Task<FFMpegInfo> GetFFMpegInfo(StartupOptions options, IProgress<double> progress)
|
||||
{
|
||||
var customffMpegPath = options.GetOption("-ffmpeg");
|
||||
var customffProbePath = options.GetOption("-ffprobe");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(customffMpegPath) && !string.IsNullOrWhiteSpace(customffProbePath))
|
||||
{
|
||||
return new FFMpegInfo
|
||||
{
|
||||
ProbePath = customffProbePath,
|
||||
EncoderPath = customffMpegPath,
|
||||
Version = "custom"
|
||||
};
|
||||
}
|
||||
|
||||
var rootEncoderPath = Path.Combine(_appPaths.ProgramDataPath, "ffmpeg");
|
||||
var versionedDirectoryPath = Path.Combine(rootEncoderPath, FFMpegDownloadInfo.Version);
|
||||
|
||||
|
@ -52,6 +67,8 @@ namespace MediaBrowser.ServerApplication.FFMpeg
|
|||
|
||||
Directory.CreateDirectory(versionedDirectoryPath);
|
||||
|
||||
var excludeFromDeletions = new List<string> { versionedDirectoryPath };
|
||||
|
||||
if (!File.Exists(info.ProbePath) || !File.Exists(info.EncoderPath))
|
||||
{
|
||||
// ffmpeg not present. See if there's an older version we can start with
|
||||
|
@ -71,14 +88,42 @@ namespace MediaBrowser.ServerApplication.FFMpeg
|
|||
|
||||
info = existingVersion;
|
||||
versionedDirectoryPath = Path.GetDirectoryName(info.EncoderPath);
|
||||
|
||||
excludeFromDeletions.Add(versionedDirectoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
await DownloadFonts(versionedDirectoryPath).ConfigureAwait(false);
|
||||
|
||||
DeleteOlderFolders(Path.GetDirectoryName(versionedDirectoryPath), excludeFromDeletions);
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
private void DeleteOlderFolders(string path, IEnumerable<string> excludeFolders )
|
||||
{
|
||||
var folders = Directory.GetDirectories(path)
|
||||
.Where(i => !excludeFolders.Contains(i, StringComparer.OrdinalIgnoreCase))
|
||||
.ToList();
|
||||
|
||||
foreach (var folder in folders)
|
||||
{
|
||||
DeleteFolder(folder);
|
||||
}
|
||||
}
|
||||
|
||||
private void DeleteFolder(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
Directory.Delete(path, true);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error deleting {0}", ex, path);
|
||||
}
|
||||
}
|
||||
|
||||
private FFMpegInfo GetExistingVersion(FFMpegInfo info, string rootEncoderPath)
|
||||
{
|
||||
var encoderFilename = Path.GetFileName(info.EncoderPath);
|
||||
|
|
28
MediaBrowser.ServerApplication/IO/StartupOptions.cs
Normal file
28
MediaBrowser.ServerApplication/IO/StartupOptions.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.ServerApplication.IO
|
||||
{
|
||||
public class StartupOptions
|
||||
{
|
||||
private readonly List<string> _options = Environment.GetCommandLineArgs().ToList();
|
||||
|
||||
public bool ContainsOption(string option)
|
||||
{
|
||||
return _options.Contains(option, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public string GetOption(string name)
|
||||
{
|
||||
var index = _options.IndexOf(name);
|
||||
|
||||
if (index != -1)
|
||||
{
|
||||
return _options.ElementAtOrDefault(index + 1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
using MediaBrowser.Common.Implementations.Logging;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Server.Implementations;
|
||||
using MediaBrowser.ServerApplication.IO;
|
||||
using MediaBrowser.ServerApplication.Native;
|
||||
using MediaBrowser.ServerApplication.Splash;
|
||||
using MediaBrowser.ServerApplication.Updates;
|
||||
|
@ -32,8 +33,8 @@ namespace MediaBrowser.ServerApplication
|
|||
/// </summary>
|
||||
public static void Main()
|
||||
{
|
||||
var startFlag = Environment.GetCommandLineArgs().ElementAtOrDefault(1);
|
||||
_isRunningAsService = string.Equals(startFlag, "-service", StringComparison.OrdinalIgnoreCase);
|
||||
var options = new StartupOptions();
|
||||
_isRunningAsService = options.ContainsOption("-service");
|
||||
|
||||
var applicationPath = Process.GetCurrentProcess().MainModule.FileName;
|
||||
|
||||
|
@ -48,7 +49,7 @@ namespace MediaBrowser.ServerApplication
|
|||
BeginLog(logger, appPaths);
|
||||
|
||||
// Install directly
|
||||
if (string.Equals(startFlag, "-installservice", StringComparison.OrdinalIgnoreCase))
|
||||
if (options.ContainsOption("-installservice"))
|
||||
{
|
||||
logger.Info("Performing service installation");
|
||||
InstallService(applicationPath, logger);
|
||||
|
@ -56,7 +57,7 @@ namespace MediaBrowser.ServerApplication
|
|||
}
|
||||
|
||||
// Restart with admin rights, then install
|
||||
if (string.Equals(startFlag, "-installserviceasadmin", StringComparison.OrdinalIgnoreCase))
|
||||
if (options.ContainsOption("-installserviceasadmin"))
|
||||
{
|
||||
logger.Info("Performing service installation");
|
||||
RunServiceInstallation(applicationPath);
|
||||
|
@ -64,7 +65,7 @@ namespace MediaBrowser.ServerApplication
|
|||
}
|
||||
|
||||
// Uninstall directly
|
||||
if (string.Equals(startFlag, "-uninstallservice", StringComparison.OrdinalIgnoreCase))
|
||||
if (options.ContainsOption("-uninstallservice"))
|
||||
{
|
||||
logger.Info("Performing service uninstallation");
|
||||
UninstallService(applicationPath, logger);
|
||||
|
@ -72,7 +73,7 @@ namespace MediaBrowser.ServerApplication
|
|||
}
|
||||
|
||||
// Restart with admin rights, then uninstall
|
||||
if (string.Equals(startFlag, "-uninstallserviceasadmin", StringComparison.OrdinalIgnoreCase))
|
||||
if (options.ContainsOption("-uninstallserviceasadmin"))
|
||||
{
|
||||
logger.Info("Performing service uninstallation");
|
||||
RunServiceUninstallation(applicationPath);
|
||||
|
@ -99,7 +100,7 @@ namespace MediaBrowser.ServerApplication
|
|||
|
||||
try
|
||||
{
|
||||
RunApplication(appPaths, logManager, _isRunningAsService);
|
||||
RunApplication(appPaths, logManager, _isRunningAsService, options);
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
@ -205,9 +206,10 @@ namespace MediaBrowser.ServerApplication
|
|||
/// <param name="appPaths">The app paths.</param>
|
||||
/// <param name="logManager">The log manager.</param>
|
||||
/// <param name="runService">if set to <c>true</c> [run service].</param>
|
||||
private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, bool runService)
|
||||
/// <param name="options">The options.</param>
|
||||
private static void RunApplication(ServerApplicationPaths appPaths, ILogManager logManager, bool runService, StartupOptions options)
|
||||
{
|
||||
_appHost = new ApplicationHost(appPaths, logManager, true, runService);
|
||||
_appHost = new ApplicationHost(appPaths, logManager, true, runService, options);
|
||||
|
||||
var initProgress = new Progress<double>();
|
||||
|
||||
|
|
|
@ -105,6 +105,7 @@
|
|||
<Compile Include="FFMpeg\FFMpegInfo.cs" />
|
||||
<Compile Include="IO\FileSystemFactory.cs" />
|
||||
<Compile Include="IO\NativeFileSystem.cs" />
|
||||
<Compile Include="IO\StartupOptions.cs" />
|
||||
<Compile Include="Logging\LogForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
|
|
@ -2101,6 +2101,9 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
<None Include="dashboard-ui\css\fonts\gotham-book.woff">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Include="dashboard-ui\css\fonts\RobotoBold.woff">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
|
|
|
@ -858,7 +858,7 @@ namespace MediaBrowser.XbmcMetadata.Savers
|
|||
return;
|
||||
}
|
||||
|
||||
var user = userManager.GetUserById(new Guid(userId));
|
||||
var user = userManager.GetUserById(userId);
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue