make metadata path configurable

pull/702/head
Luke Pulverenti 11 years ago
parent 7c94203d05
commit 31e8288393

@ -9,16 +9,14 @@ using System.Linq;
namespace MediaBrowser.Api namespace MediaBrowser.Api
{ {
[Route("/Themes", "GET")] [Route("/Themes", "GET", Summary = "Gets a list of available themes for an app")]
[Api(Description = "Gets a list of available themes for an app")]
public class GetAppThemes : IReturn<List<AppThemeInfo>> public class GetAppThemes : IReturn<List<AppThemeInfo>>
{ {
[ApiMember(Name = "App", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "App", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
public string App { get; set; } public string App { get; set; }
} }
[Route("/Themes/Info", "GET")] [Route("/Themes/Info", "GET", Summary = "Gets an app theme")]
[Api(Description = "Gets an app theme")]
public class GetAppTheme : IReturn<AppTheme> public class GetAppTheme : IReturn<AppTheme>
{ {
[ApiMember(Name = "App", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "App", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
@ -28,8 +26,7 @@ namespace MediaBrowser.Api
public string Name { get; set; } public string Name { get; set; }
} }
[Route("/Themes/Images", "GET")] [Route("/Themes/Images", "GET", Summary = "Gets an app theme")]
[Api(Description = "Gets an app theme")]
public class GetAppThemeImage public class GetAppThemeImage
{ {
[ApiMember(Name = "App", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "App", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
@ -45,12 +42,11 @@ namespace MediaBrowser.Api
public string CacheTag { get; set; } public string CacheTag { get; set; }
} }
[Route("/Themes", "POST")] [Route("/Themes", "POST", Summary = "Saves a theme")]
[Api(Description = "Saves a theme")]
public class SaveTheme : AppTheme, IReturnVoid public class SaveTheme : AppTheme, IReturnVoid
{ {
} }
public class AppThemeService : BaseApiService public class AppThemeService : BaseApiService
{ {
private readonly IAppThemeManager _themeManager; private readonly IAppThemeManager _themeManager;

@ -2,6 +2,7 @@
using MediaBrowser.Controller.Entities.Audio; using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Logging; using MediaBrowser.Model.Logging;
using ServiceStack.Web; using ServiceStack.Web;
using System; using System;
@ -78,6 +79,20 @@ namespace MediaBrowser.Api
return ToOptimizedResult(result); return ToOptimizedResult(result);
} }
/// <summary>
/// Gets the session.
/// </summary>
/// <param name="sessionManager">The session manager.</param>
/// <returns>SessionInfo.</returns>
protected SessionInfo GetSession(ISessionManager sessionManager)
{
var auth = AuthorizationRequestFilterAttribute.GetAuthorization(Request);
return sessionManager.Sessions.First(i => string.Equals(i.DeviceId, auth.DeviceId) &&
string.Equals(i.Client, auth.Client) &&
string.Equals(i.ApplicationVersion, auth.Version));
}
/// <summary> /// <summary>
/// To the cached result. /// To the cached result.
/// </summary> /// </summary>

@ -17,8 +17,7 @@ namespace MediaBrowser.Api
/// <summary> /// <summary>
/// Class GetConfiguration /// Class GetConfiguration
/// </summary> /// </summary>
[Route("/System/Configuration", "GET")] [Route("/System/Configuration", "GET", Summary = "Gets application configuration")]
[Api(("Gets application configuration"))]
public class GetConfiguration : IReturn<ServerConfiguration> public class GetConfiguration : IReturn<ServerConfiguration>
{ {
@ -27,28 +26,24 @@ namespace MediaBrowser.Api
/// <summary> /// <summary>
/// Class UpdateConfiguration /// Class UpdateConfiguration
/// </summary> /// </summary>
[Route("/System/Configuration", "POST")] [Route("/System/Configuration", "POST", Summary = "Updates application configuration")]
[Api(("Updates application configuration"))]
public class UpdateConfiguration : ServerConfiguration, IReturnVoid public class UpdateConfiguration : ServerConfiguration, IReturnVoid
{ {
} }
[Route("/System/Configuration/MetadataOptions/Default", "GET")] [Route("/System/Configuration/MetadataOptions/Default", "GET", Summary = "Gets a default MetadataOptions object")]
[Api(("Gets a default MetadataOptions object"))]
public class GetDefaultMetadataOptions : IReturn<MetadataOptions> public class GetDefaultMetadataOptions : IReturn<MetadataOptions>
{ {
} }
[Route("/System/Configuration/MetadataPlugins", "GET")] [Route("/System/Configuration/MetadataPlugins", "GET", Summary = "Gets all available metadata plugins")]
[Api(("Gets all available metadata plugins"))]
public class GetMetadataPlugins : IReturn<List<MetadataPluginSummary>> public class GetMetadataPlugins : IReturn<List<MetadataPluginSummary>>
{ {
} }
[Route("/System/Configuration/VideoImageExtraction", "POST")] [Route("/System/Configuration/VideoImageExtraction", "POST", Summary = "Updates image extraction for all types")]
[Api(("Updates image extraction for all types"))]
public class UpdateVideoImageExtraction : IReturnVoid public class UpdateVideoImageExtraction : IReturnVoid
{ {
public bool Enabled { get; set; } public bool Enabled { get; set; }

@ -7,6 +7,7 @@ using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV; 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.Model.Channels; using MediaBrowser.Model.Channels;
using MediaBrowser.Model.Dto; using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
@ -245,12 +246,13 @@ namespace MediaBrowser.Api.Library
private readonly IDtoService _dtoService; private readonly IDtoService _dtoService;
private readonly IChannelManager _channelManager; private readonly IChannelManager _channelManager;
private readonly ISessionManager _sessionManager;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="LibraryService" /> class. /// Initializes a new instance of the <see cref="LibraryService" /> class.
/// </summary> /// </summary>
public LibraryService(IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager, public LibraryService(IItemRepository itemRepo, ILibraryManager libraryManager, IUserManager userManager,
IDtoService dtoService, IUserDataManager userDataManager, IChannelManager channelManager) IDtoService dtoService, IUserDataManager userDataManager, IChannelManager channelManager, ISessionManager sessionManager)
{ {
_itemRepo = itemRepo; _itemRepo = itemRepo;
_libraryManager = libraryManager; _libraryManager = libraryManager;
@ -258,6 +260,7 @@ namespace MediaBrowser.Api.Library
_dtoService = dtoService; _dtoService = dtoService;
_userDataManager = userDataManager; _userDataManager = userDataManager;
_channelManager = channelManager; _channelManager = channelManager;
_sessionManager = sessionManager;
} }
public object Get(GetMediaFolders request) public object Get(GetMediaFolders request)
@ -504,6 +507,13 @@ namespace MediaBrowser.Api.Library
{ {
var item = _dtoService.GetItemByDtoId(request.Id); var item = _dtoService.GetItemByDtoId(request.Id);
var session = GetSession(_sessionManager);
if (!session.UserId.HasValue || !_userManager.GetUserById(session.UserId.Value).Configuration.EnableContentDeletion)
{
throw new UnauthorizedAccessException("This operation requires a logged in user with delete access.");
}
return _libraryManager.DeleteItem(item); return _libraryManager.DeleteItem(item);
} }

@ -17,8 +17,7 @@ namespace MediaBrowser.Api.Movies
/// <summary> /// <summary>
/// Class GetSimilarMovies /// Class GetSimilarMovies
/// </summary> /// </summary>
[Route("/Movies/{Id}/Similar", "GET")] [Route("/Movies/{Id}/Similar", "GET", Summary = "Finds movies and trailers similar to a given movie.")]
[Api(Description = "Finds movies and trailers similar to a given movie.")]
public class GetSimilarMovies : BaseGetSimilarItemsFromItem public class GetSimilarMovies : BaseGetSimilarItemsFromItem
{ {
[ApiMember(Name = "IncludeTrailers", Description = "Whether or not to include trailers within the results. Defaults to true.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "IncludeTrailers", Description = "Whether or not to include trailers within the results. Defaults to true.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
@ -30,8 +29,7 @@ namespace MediaBrowser.Api.Movies
} }
} }
[Route("/Movies/Recommendations", "GET")] [Route("/Movies/Recommendations", "GET", Summary = "Gets movie recommendations")]
[Api(Description = "Gets movie recommendations")]
public class GetMovieRecommendations : IReturn<RecommendationDto[]>, IHasItemFields public class GetMovieRecommendations : IReturn<RecommendationDto[]>, IHasItemFields
{ {
[ApiMember(Name = "CategoryLimit", Description = "The max number of categories to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "CategoryLimit", Description = "The max number of categories to return", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]

@ -10,8 +10,7 @@ namespace MediaBrowser.Api.Movies
/// <summary> /// <summary>
/// Class GetSimilarTrailers /// Class GetSimilarTrailers
/// </summary> /// </summary>
[Route("/Trailers/{Id}/Similar", "GET")] [Route("/Trailers/{Id}/Similar", "GET", Summary = "Finds movies and trailers similar to a given trailer.")]
[Api(Description = "Finds movies and trailers similar to a given trailer.")]
public class GetSimilarTrailers : BaseGetSimilarItemsFromItem public class GetSimilarTrailers : BaseGetSimilarItemsFromItem
{ {
} }

@ -9,28 +9,24 @@ using System.Linq;
namespace MediaBrowser.Api.Music namespace MediaBrowser.Api.Music
{ {
[Route("/Songs/{Id}/InstantMix", "GET")] [Route("/Songs/{Id}/InstantMix", "GET", Summary = "Creates an instant playlist based on a given song")]
[Api(Description = "Creates an instant playlist based on a given song")]
public class GetInstantMixFromSong : BaseGetSimilarItemsFromItem public class GetInstantMixFromSong : BaseGetSimilarItemsFromItem
{ {
} }
[Route("/Albums/{Id}/InstantMix", "GET")] [Route("/Albums/{Id}/InstantMix", "GET", Summary = "Creates an instant playlist based on a given album")]
[Api(Description = "Creates an instant playlist based on a given album")]
public class GetInstantMixFromAlbum : BaseGetSimilarItemsFromItem public class GetInstantMixFromAlbum : BaseGetSimilarItemsFromItem
{ {
} }
[Route("/Artists/{Name}/InstantMix", "GET")] [Route("/Artists/{Name}/InstantMix", "GET", Summary = "Creates an instant playlist based on a given artist")]
[Api(Description = "Creates an instant playlist based on a given artist")]
public class GetInstantMixFromArtist : BaseGetSimilarItems public class GetInstantMixFromArtist : BaseGetSimilarItems
{ {
[ApiMember(Name = "Name", Description = "The artist name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] [ApiMember(Name = "Name", Description = "The artist name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Name { get; set; } public string Name { get; set; }
} }
[Route("/MusicGenres/{Name}/InstantMix", "GET")] [Route("/MusicGenres/{Name}/InstantMix", "GET", Summary = "Creates an instant playlist based on a music genre")]
[Api(Description = "Creates an instant playlist based on a music genre")]
public class GetInstantMixFromMusicGenre : BaseGetSimilarItems public class GetInstantMixFromMusicGenre : BaseGetSimilarItems
{ {
[ApiMember(Name = "Name", Description = "The genre name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")] [ApiMember(Name = "Name", Description = "The genre name", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]

@ -2,18 +2,17 @@
using MediaBrowser.Common.ScheduledTasks; using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Model.Tasks; using MediaBrowser.Model.Tasks;
using ServiceStack; using ServiceStack;
using ServiceStack.Text.Controller;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using ServiceStack.Text.Controller;
namespace MediaBrowser.Api.ScheduledTasks namespace MediaBrowser.Api.ScheduledTasks
{ {
/// <summary> /// <summary>
/// Class GetScheduledTask /// Class GetScheduledTask
/// </summary> /// </summary>
[Route("/ScheduledTasks/{Id}", "GET")] [Route("/ScheduledTasks/{Id}", "GET", Summary = "Gets a scheduled task, by Id")]
[Api(Description = "Gets a scheduled task, by Id")]
public class GetScheduledTask : IReturn<TaskInfo> public class GetScheduledTask : IReturn<TaskInfo>
{ {
/// <summary> /// <summary>
@ -27,8 +26,7 @@ namespace MediaBrowser.Api.ScheduledTasks
/// <summary> /// <summary>
/// Class GetScheduledTasks /// Class GetScheduledTasks
/// </summary> /// </summary>
[Route("/ScheduledTasks", "GET")] [Route("/ScheduledTasks", "GET", Summary = "Gets scheduled tasks")]
[Api(Description = "Gets scheduled tasks")]
public class GetScheduledTasks : IReturn<List<TaskInfo>> public class GetScheduledTasks : IReturn<List<TaskInfo>>
{ {
[ApiMember(Name = "IsHidden", Description = "Optional filter tasks that are hidden, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")] [ApiMember(Name = "IsHidden", Description = "Optional filter tasks that are hidden, or not.", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
@ -38,8 +36,7 @@ namespace MediaBrowser.Api.ScheduledTasks
/// <summary> /// <summary>
/// Class StartScheduledTask /// Class StartScheduledTask
/// </summary> /// </summary>
[Route("/ScheduledTasks/Running/{Id}", "POST")] [Route("/ScheduledTasks/Running/{Id}", "POST", Summary = "Starts a scheduled task")]
[Api(Description = "Starts a scheduled task")]
public class StartScheduledTask : IReturnVoid public class StartScheduledTask : IReturnVoid
{ {
/// <summary> /// <summary>
@ -53,8 +50,7 @@ namespace MediaBrowser.Api.ScheduledTasks
/// <summary> /// <summary>
/// Class StopScheduledTask /// Class StopScheduledTask
/// </summary> /// </summary>
[Route("/ScheduledTasks/Running/{Id}", "DELETE")] [Route("/ScheduledTasks/Running/{Id}", "DELETE", Summary = "Stops a scheduled task")]
[Api(Description = "Stops a scheduled task")]
public class StopScheduledTask : IReturnVoid public class StopScheduledTask : IReturnVoid
{ {
/// <summary> /// <summary>
@ -68,8 +64,7 @@ namespace MediaBrowser.Api.ScheduledTasks
/// <summary> /// <summary>
/// Class UpdateScheduledTaskTriggers /// Class UpdateScheduledTaskTriggers
/// </summary> /// </summary>
[Route("/ScheduledTasks/{Id}/Triggers", "POST")] [Route("/ScheduledTasks/{Id}/Triggers", "POST", Summary = "Updates the triggers for a scheduled task")]
[Api(Description = "Updates the triggers for a scheduled task")]
public class UpdateScheduledTaskTriggers : List<TaskTriggerInfo>, IReturnVoid public class UpdateScheduledTaskTriggers : List<TaskTriggerInfo>, IReturnVoid
{ {
/// <summary> /// <summary>

@ -8,15 +8,13 @@ using ServiceStack;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
namespace MediaBrowser.Api.UserLibrary namespace MediaBrowser.Api.UserLibrary
{ {
/// <summary> /// <summary>
/// Class GetStudios /// Class GetStudios
/// </summary> /// </summary>
[Route("/Studios", "GET")] [Route("/Studios", "GET", Summary = "Gets all studios from a given item, folder, or the entire library")]
[Api(Description = "Gets all studios from a given item, folder, or the entire library")]
public class GetStudios : GetItemsByName public class GetStudios : GetItemsByName
{ {
} }
@ -24,8 +22,7 @@ namespace MediaBrowser.Api.UserLibrary
/// <summary> /// <summary>
/// Class GetStudio /// Class GetStudio
/// </summary> /// </summary>
[Route("/Studios/{Name}", "GET")] [Route("/Studios/{Name}", "GET", Summary = "Gets a studio, by name")]
[Api(Description = "Gets a studio, by name")]
public class GetStudio : IReturn<BaseItemDto> public class GetStudio : IReturn<BaseItemDto>
{ {
/// <summary> /// <summary>

@ -705,7 +705,7 @@ namespace MediaBrowser.Api.UserLibrary
datePlayed = DateTime.ParseExact(request.DatePlayed, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); datePlayed = DateTime.ParseExact(request.DatePlayed, "yyyyMMddHHmmss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal);
} }
var session = GetSession(); var session = GetSession(_sessionManager);
var dto = await UpdatePlayedStatus(user, request.Id, true, datePlayed).ConfigureAwait(false); var dto = await UpdatePlayedStatus(user, request.Id, true, datePlayed).ConfigureAwait(false);
@ -719,15 +719,6 @@ namespace MediaBrowser.Api.UserLibrary
return dto; return dto;
} }
private SessionInfo GetSession()
{
var auth = AuthorizationRequestFilterAttribute.GetAuthorization(Request);
return _sessionManager.Sessions.First(i => string.Equals(i.DeviceId, auth.DeviceId) &&
string.Equals(i.Client, auth.Client) &&
string.Equals(i.ApplicationVersion, auth.Version));
}
/// <summary> /// <summary>
/// Posts the specified request. /// Posts the specified request.
/// </summary> /// </summary>
@ -744,7 +735,7 @@ namespace MediaBrowser.Api.UserLibrary
{ {
CanSeek = request.CanSeek, CanSeek = request.CanSeek,
Item = item, Item = item,
SessionId = GetSession().Id, SessionId = GetSession(_sessionManager).Id,
QueueableMediaTypes = queueableMediaTypes.Split(',').ToList(), QueueableMediaTypes = queueableMediaTypes.Split(',').ToList(),
MediaSourceId = request.MediaSourceId MediaSourceId = request.MediaSourceId
}; };
@ -768,7 +759,7 @@ namespace MediaBrowser.Api.UserLibrary
PositionTicks = request.PositionTicks, PositionTicks = request.PositionTicks,
IsMuted = request.IsMuted, IsMuted = request.IsMuted,
IsPaused = request.IsPaused, IsPaused = request.IsPaused,
SessionId = GetSession().Id, SessionId = GetSession(_sessionManager).Id,
MediaSourceId = request.MediaSourceId MediaSourceId = request.MediaSourceId
}; };
@ -787,7 +778,7 @@ namespace MediaBrowser.Api.UserLibrary
var item = _dtoService.GetItemByDtoId(request.Id, user.Id); var item = _dtoService.GetItemByDtoId(request.Id, user.Id);
var session = GetSession(); var session = GetSession(_sessionManager);
var info = new PlaybackStopInfo var info = new PlaybackStopInfo
{ {
@ -817,7 +808,7 @@ namespace MediaBrowser.Api.UserLibrary
{ {
var user = _userManager.GetUserById(request.UserId); var user = _userManager.GetUserById(request.UserId);
var session = GetSession(); var session = GetSession(_sessionManager);
var dto = await UpdatePlayedStatus(user, request.Id, false, null).ConfigureAwait(false); var dto = await UpdatePlayedStatus(user, request.Id, false, null).ConfigureAwait(false);

@ -49,7 +49,7 @@ namespace MediaBrowser.Api.WebSocket
/// <returns>Task{SystemInfo}.</returns> /// <returns>Task{SystemInfo}.</returns>
protected override Task<IEnumerable<SessionInfoDto>> GetDataToSend(object state) protected override Task<IEnumerable<SessionInfoDto>> GetDataToSend(object state)
{ {
return Task.FromResult(_sessionManager.Sessions.Select(_dtoService.GetSessionInfoDto)); return Task.FromResult(_sessionManager.Sessions.Where(i => i.IsActive).Select(_dtoService.GetSessionInfoDto));
} }
} }
} }

@ -69,8 +69,6 @@ namespace MediaBrowser.Controller.Dlna
VideoBitrate, VideoBitrate,
VideoFramerate, VideoFramerate,
VideoLevel, VideoLevel,
VideoPacketLength, VideoProfile
VideoProfile,
VideoTimestamp
} }
} }

@ -121,10 +121,7 @@ namespace MediaBrowser.Controller.Entities
{ {
_configuration = value; _configuration = value;
if (value == null) _configurationInitialized = value != null;
{
_configurationInitialized = false;
}
} }
} }

@ -241,7 +241,13 @@ namespace MediaBrowser.Dlna.PlayTo
_sessionManager.ReportCapabilities(sessionInfo.Id, new SessionCapabilities _sessionManager.ReportCapabilities(sessionInfo.Id, new SessionCapabilities
{ {
PlayableMediaTypes = new[] { MediaType.Audio, MediaType.Video, MediaType.Photo }, PlayableMediaTypes = new[]
{
MediaType.Audio,
MediaType.Video,
MediaType.Photo
},
SupportsFullscreenToggle = false SupportsFullscreenToggle = false
}); });

@ -191,9 +191,7 @@ namespace MediaBrowser.Dlna.PlayTo
case ProfileConditionValue.AudioProfile: case ProfileConditionValue.AudioProfile:
case ProfileConditionValue.Has64BitOffsets: case ProfileConditionValue.Has64BitOffsets:
case ProfileConditionValue.VideoBitDepth: case ProfileConditionValue.VideoBitDepth:
case ProfileConditionValue.VideoPacketLength:
case ProfileConditionValue.VideoProfile: case ProfileConditionValue.VideoProfile:
case ProfileConditionValue.VideoTimestamp:
{ {
// Not supported yet // Not supported yet
break; break;
@ -461,12 +459,6 @@ namespace MediaBrowser.Dlna.PlayTo
return videoStream == null ? null : videoStream.Width; return videoStream == null ? null : videoStream.Width;
case ProfileConditionValue.VideoLevel: case ProfileConditionValue.VideoLevel:
return videoStream == null ? null : ConvertToLong(videoStream.Level); return videoStream == null ? null : ConvertToLong(videoStream.Level);
case ProfileConditionValue.VideoPacketLength:
// TODO: Determine how to get this
return null;
case ProfileConditionValue.VideoTimestamp:
// TODO: Determine how to get this
return null;
default: default:
throw new InvalidOperationException("Unexpected Property"); throw new InvalidOperationException("Unexpected Property");
} }

@ -22,7 +22,11 @@ namespace MediaBrowser.Dlna.PlayTo
_config = config; _config = config;
} }
public async Task<XDocument> SendCommandAsync(string baseUrl, DeviceService service, string command, string postData, string header = null) public async Task<XDocument> SendCommandAsync(string baseUrl,
DeviceService service,
string command,
string postData,
string header = null)
{ {
var serviceUrl = service.ControlUrl; var serviceUrl = service.ControlUrl;
if (!serviceUrl.StartsWith("/")) if (!serviceUrl.StartsWith("/"))
@ -40,7 +44,12 @@ namespace MediaBrowser.Dlna.PlayTo
} }
} }
public async Task SubscribeAsync(string url, string ip, int port, string localIp, int eventport, int timeOut = 3600) public async Task SubscribeAsync(string url,
string ip,
int port,
string localIp,
int eventport,
int timeOut = 3600)
{ {
var options = new HttpRequestOptions var options = new HttpRequestOptions
{ {
@ -59,7 +68,11 @@ namespace MediaBrowser.Dlna.PlayTo
} }
} }
public async Task RespondAsync(Uri url, string ip, int port, string localIp, int eventport, int timeOut = 20000) public async Task RespondAsync(Uri url,
string ip,
int port,
string localIp,
int eventport)
{ {
var options = new HttpRequestOptions var options = new HttpRequestOptions
{ {
@ -97,7 +110,10 @@ namespace MediaBrowser.Dlna.PlayTo
} }
} }
private Task<HttpResponseInfo> PostSoapDataAsync(string url, string soapAction, string postData, string header = null) private Task<HttpResponseInfo> PostSoapDataAsync(string url,
string soapAction,
string postData,
string header = null)
{ {
if (!soapAction.StartsWith("\"")) if (!soapAction.StartsWith("\""))
soapAction = "\"" + soapAction + "\""; soapAction = "\"" + soapAction + "\"";

@ -1,8 +1,6 @@
using MediaBrowser.Controller.Dlna; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Entities;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.Linq;
namespace MediaBrowser.Dlna.PlayTo namespace MediaBrowser.Dlna.PlayTo
{ {

@ -6,7 +6,7 @@ namespace MediaBrowser.Dlna.Profiles
{ {
public DefaultProfile() public DefaultProfile()
{ {
Name = "Generic Device"; Name = "Media Browser";
ProtocolInfo = "DLNA"; ProtocolInfo = "DLNA";

@ -96,13 +96,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3", AudioCodec="ac3,aac,mp3",
MimeType = "video/vnd.dlna.mpeg-tts", MimeType = "video/vnd.dlna.mpeg-tts",
OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T", OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T",
Type = DlnaProfileType.Video, Type = DlnaProfileType.Video
Conditions = new []
{
new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="192"},
new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoTimestamp, Value="1"}
}
}, },
new MediaProfile new MediaProfile
@ -112,12 +106,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3", AudioCodec="ac3,aac,mp3",
MimeType = "video/mpeg", MimeType = "video/mpeg",
OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO", OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO",
Type = DlnaProfileType.Video, Type = DlnaProfileType.Video
Conditions = new []
{
new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="188"}
}
}, },
new MediaProfile new MediaProfile

@ -138,13 +138,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3", AudioCodec="ac3,aac,mp3",
MimeType = "video/vnd.dlna.mpeg-tts", MimeType = "video/vnd.dlna.mpeg-tts",
OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T", OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T",
Type = DlnaProfileType.Video, Type = DlnaProfileType.Video
Conditions = new []
{
new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="192"},
new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoTimestamp, Value="1"}
}
}, },
new MediaProfile new MediaProfile
@ -154,12 +148,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3", AudioCodec="ac3,aac,mp3",
MimeType = "video/mpeg", MimeType = "video/mpeg",
OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO", OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO",
Type = DlnaProfileType.Video, Type = DlnaProfileType.Video
Conditions = new []
{
new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="188"}
}
}, },
new MediaProfile new MediaProfile

@ -126,13 +126,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3", AudioCodec="ac3,aac,mp3",
MimeType = "video/vnd.dlna.mpeg-tts", MimeType = "video/vnd.dlna.mpeg-tts",
OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T", OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T",
Type = DlnaProfileType.Video, Type = DlnaProfileType.Video
Conditions = new []
{
new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="192"},
new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoTimestamp, Value="1"}
}
}, },
new MediaProfile new MediaProfile
@ -142,12 +136,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3", AudioCodec="ac3,aac,mp3",
MimeType = "video/mpeg", MimeType = "video/mpeg",
OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO", OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO",
Type = DlnaProfileType.Video, Type = DlnaProfileType.Video
Conditions = new []
{
new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="188"}
}
}, },
new MediaProfile new MediaProfile

@ -182,13 +182,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3", AudioCodec="ac3,aac,mp3",
MimeType = "video/vnd.dlna.mpeg-tts", MimeType = "video/vnd.dlna.mpeg-tts",
OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T", OrgPn="AVC_TS_HD_24_AC3_T,AVC_TS_HD_50_AC3_T,AVC_TS_HD_60_AC3_T,AVC_TS_HD_EU_T",
Type = DlnaProfileType.Video, Type = DlnaProfileType.Video
Conditions = new []
{
new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="192"},
new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoTimestamp, Value="1"}
}
}, },
new MediaProfile new MediaProfile
@ -198,12 +192,7 @@ namespace MediaBrowser.Dlna.Profiles
AudioCodec="ac3,aac,mp3", AudioCodec="ac3,aac,mp3",
MimeType = "video/mpeg", MimeType = "video/mpeg",
OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO", OrgPn="AVC_TS_HD_24_AC3_ISO,AVC_TS_HD_50_AC3_ISO,AVC_TS_HD_60_AC3_ISO,AVC_TS_HD_EU_ISO",
Type = DlnaProfileType.Video, Type = DlnaProfileType.Video
Conditions = new []
{
new ProfileCondition{ Condition= ProfileConditionType.Equals, Property= ProfileConditionValue.VideoPacketLength, Value="188"}
}
}, },
new MediaProfile new MediaProfile

@ -57,6 +57,12 @@ namespace MediaBrowser.Model.Configuration
/// <value>The item by name path.</value> /// <value>The item by name path.</value>
public string ItemsByNamePath { get; set; } public string ItemsByNamePath { get; set; }
/// <summary>
/// Gets or sets the metadata path.
/// </summary>
/// <value>The metadata path.</value>
public string MetadataPath { get; set; }
/// <summary> /// <summary>
/// Gets or sets the display name of the season zero. /// Gets or sets the display name of the season zero.
/// </summary> /// </summary>

@ -52,6 +52,7 @@ namespace MediaBrowser.Model.Configuration
public bool EnableLiveTvAccess { get; set; } public bool EnableLiveTvAccess { get; set; }
public bool EnableMediaPlayback { get; set; } public bool EnableMediaPlayback { get; set; }
public bool EnableContentDeletion { get; set; }
public string[] BlockedMediaFolders { get; set; } public string[] BlockedMediaFolders { get; set; }
@ -63,8 +64,9 @@ namespace MediaBrowser.Model.Configuration
public UserConfiguration() public UserConfiguration()
{ {
IsAdministrator = true; IsAdministrator = true;
EnableRemoteControlOfOtherUsers = true;
EnableRemoteControlOfOtherUsers = true;
EnableContentDeletion = true;
EnableLiveTvManagement = true; EnableLiveTvManagement = true;
EnableMediaPlayback = true; EnableMediaPlayback = true;
EnableLiveTvAccess = true; EnableLiveTvAccess = true;

@ -148,7 +148,7 @@ namespace MediaBrowser.Providers.MediaInfo
if (!string.IsNullOrWhiteSpace(composer)) if (!string.IsNullOrWhiteSpace(composer))
{ {
foreach (var person in Split(composer)) foreach (var person in Split(composer, false))
{ {
audio.AddPerson(new PersonInfo { Name = person, Type = PersonType.Composer }); audio.AddPerson(new PersonInfo { Name = person, Type = PersonType.Composer });
} }
@ -221,12 +221,15 @@ namespace MediaBrowser.Providers.MediaInfo
/// Splits the specified val. /// Splits the specified val.
/// </summary> /// </summary>
/// <param name="val">The val.</param> /// <param name="val">The val.</param>
/// <param name="allowCommaDelimiter">if set to <c>true</c> [allow comma delimiter].</param>
/// <returns>System.String[][].</returns> /// <returns>System.String[][].</returns>
private IEnumerable<string> Split(string val) private IEnumerable<string> Split(string val, bool allowCommaDelimiter)
{ {
// Only use the comma as a delimeter if there are no slashes or pipes. // Only use the comma as a delimeter if there are no slashes or pipes.
// We want to be careful not to split names that have commas in them // We want to be careful not to split names that have commas in them
var delimeter = _nameDelimiters.Any(i => val.IndexOf(i) != -1) ? _nameDelimiters : new[] { ',' }; var delimeter = !allowCommaDelimiter || _nameDelimiters.Any(i => val.IndexOf(i) != -1) ?
_nameDelimiters :
new[] { ',' };
return val.Split(delimeter, StringSplitOptions.RemoveEmptyEntries) return val.Split(delimeter, StringSplitOptions.RemoveEmptyEntries)
.Where(i => !string.IsNullOrWhiteSpace(i)) .Where(i => !string.IsNullOrWhiteSpace(i))
@ -312,7 +315,7 @@ namespace MediaBrowser.Providers.MediaInfo
if (!string.IsNullOrEmpty(val)) if (!string.IsNullOrEmpty(val))
{ {
// Sometimes the artist name is listed here, account for that // Sometimes the artist name is listed here, account for that
var studios = Split(val).Where(i => !audio.HasArtist(i)); var studios = Split(val, true).Where(i => !audio.HasArtist(i));
foreach (var studio in studios) foreach (var studio in studios)
{ {
@ -334,7 +337,7 @@ namespace MediaBrowser.Providers.MediaInfo
{ {
audio.Genres.Clear(); audio.Genres.Clear();
foreach (var genre in Split(val)) foreach (var genre in Split(val, true))
{ {
audio.AddGenre(genre); audio.AddGenre(genre);
} }

@ -26,6 +26,7 @@ namespace MediaBrowser.Server.Implementations.Configuration
{ {
UpdateItemsByNamePath(); UpdateItemsByNamePath();
UpdateTranscodingTempPath(); UpdateTranscodingTempPath();
UpdateMetadataPath();
} }
/// <summary> /// <summary>
@ -76,6 +77,16 @@ namespace MediaBrowser.Server.Implementations.Configuration
Configuration.ItemsByNamePath; Configuration.ItemsByNamePath;
} }
/// <summary>
/// Updates the metadata path.
/// </summary>
private void UpdateMetadataPath()
{
((ServerApplicationPaths)ApplicationPaths).InternalMetadataPath = string.IsNullOrEmpty(Configuration.MetadataPath) ?
null :
Configuration.MetadataPath;
}
/// <summary> /// <summary>
/// Updates the transcoding temporary path. /// Updates the transcoding temporary path.
/// </summary> /// </summary>
@ -98,6 +109,7 @@ namespace MediaBrowser.Server.Implementations.Configuration
ValidateItemByNamePath(newConfig); ValidateItemByNamePath(newConfig);
ValidateTranscodingTempPath(newConfig); ValidateTranscodingTempPath(newConfig);
ValidatePathSubstitutions(newConfig); ValidatePathSubstitutions(newConfig);
ValidateMetadataPath(newConfig);
base.ReplaceConfiguration(newConfiguration); base.ReplaceConfiguration(newConfiguration);
} }
@ -166,5 +178,25 @@ namespace MediaBrowser.Server.Implementations.Configuration
} }
} }
} }
/// <summary>
/// Validates the metadata path.
/// </summary>
/// <param name="newConfig">The new configuration.</param>
/// <exception cref="System.IO.DirectoryNotFoundException"></exception>
private void ValidateMetadataPath(ServerConfiguration newConfig)
{
var newPath = newConfig.MetadataPath;
if (!string.IsNullOrWhiteSpace(newPath)
&& !string.Equals(Configuration.MetadataPath ?? string.Empty, newPath))
{
// Validate
if (!Directory.Exists(newPath))
{
throw new DirectoryNotFoundException(string.Format("{0} does not exist.", newPath));
}
}
}
} }
} }

@ -260,6 +260,8 @@ namespace MediaBrowser.Server.Implementations.Library
public event EventHandler<GenericEventArgs<User>> UserCreated; public event EventHandler<GenericEventArgs<User>> UserCreated;
private readonly SemaphoreSlim _userListLock = new SemaphoreSlim(1, 1);
/// <summary> /// <summary>
/// Creates the user. /// Creates the user.
/// </summary> /// </summary>
@ -279,19 +281,28 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentException(string.Format("A user with the name '{0}' already exists.", name)); throw new ArgumentException(string.Format("A user with the name '{0}' already exists.", name));
} }
var user = InstantiateNewUser(name); await _userListLock.WaitAsync(CancellationToken.None).ConfigureAwait(false);
var list = Users.ToList(); try
list.Add(user); {
Users = list; var user = InstantiateNewUser(name);
user.DateLastSaved = DateTime.UtcNow; var list = Users.ToList();
list.Add(user);
Users = list;
await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false); user.DateLastSaved = DateTime.UtcNow;
EventHelper.QueueEventIfNotNull(UserCreated, this, new GenericEventArgs<User> { Argument = user }, _logger); await UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
return user; EventHelper.QueueEventIfNotNull(UserCreated, this, new GenericEventArgs<User> { Argument = user }, _logger);
return user;
}
finally
{
_userListLock.Release();
}
} }
/// <summary> /// <summary>
@ -325,23 +336,32 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentException(string.Format("The user '{0}' cannot be deleted because there must be at least one admin user in the system.", user.Name)); throw new ArgumentException(string.Format("The user '{0}' cannot be deleted because there must be at least one admin user in the system.", user.Name));
} }
await UserRepository.DeleteUser(user, CancellationToken.None).ConfigureAwait(false); await _userListLock.WaitAsync(CancellationToken.None).ConfigureAwait(false);
var path = user.ConfigurationFilePath;
try try
{ {
File.Delete(path); await UserRepository.DeleteUser(user, CancellationToken.None).ConfigureAwait(false);
var path = user.ConfigurationFilePath;
try
{
File.Delete(path);
}
catch (IOException ex)
{
_logger.ErrorException("Error deleting file {0}", ex, path);
}
// Force this to be lazy loaded again
Users = await LoadUsers().ConfigureAwait(false);
OnUserDeleted(user);
} }
catch (IOException ex) finally
{ {
_logger.ErrorException("Error deleting file {0}", ex, path); _userListLock.Release();
} }
// Force this to be lazy loaded again
Users = await LoadUsers().ConfigureAwait(false);
OnUserDeleted(user);
} }
/// <summary> /// <summary>

@ -1,6 +1,6 @@
using System; using MediaBrowser.Common.Implementations;
using MediaBrowser.Common.Implementations;
using MediaBrowser.Controller; using MediaBrowser.Controller;
using System;
using System.IO; using System.IO;
namespace MediaBrowser.Server.Implementations namespace MediaBrowser.Server.Implementations
@ -239,14 +239,20 @@ namespace MediaBrowser.Server.Implementations
} }
} }
private string _internalMetadataPath;
public string InternalMetadataPath public string InternalMetadataPath
{ {
get get
{ {
return Path.Combine(DataPath, "metadata"); return _internalMetadataPath ?? (_internalMetadataPath = Path.Combine(DataPath, "metadata"));
}
set
{
_internalMetadataPath = value;
} }
} }
public string GetInternalMetadataPath(Guid id) public string GetInternalMetadataPath(Guid id)
{ {
var idString = id.ToString("N"); var idString = id.ToString("N");

@ -795,7 +795,7 @@ namespace MediaBrowser.ServerApplication
list.Add(typeof(ApiEntryPoint).Assembly); list.Add(typeof(ApiEntryPoint).Assembly);
// Include composable parts in the Dashboard assembly // Include composable parts in the Dashboard assembly
list.Add(typeof(DashboardInfo).Assembly); list.Add(typeof(DashboardService).Assembly);
// Include composable parts in the Model assembly // Include composable parts in the Model assembly
list.Add(typeof(SystemInfo).Assembly); list.Add(typeof(SystemInfo).Assembly);

@ -1,39 +0,0 @@
using MediaBrowser.Model.Session;
using MediaBrowser.Model.System;
using MediaBrowser.Model.Tasks;
using System;
using System.Collections.Generic;
namespace MediaBrowser.WebDashboard.Api
{
/// <summary>
/// Class DashboardInfo
/// </summary>
public class DashboardInfo
{
/// <summary>
/// Gets or sets the system info.
/// </summary>
/// <value>The system info.</value>
public SystemInfo SystemInfo { get; set; }
/// <summary>
/// Gets or sets the running tasks.
/// </summary>
/// <value>The running tasks.</value>
public List<TaskInfo> RunningTasks { get; set; }
/// <summary>
/// Gets or sets the application update task id.
/// </summary>
/// <value>The application update task id.</value>
public Guid ApplicationUpdateTaskId { get; set; }
/// <summary>
/// Gets or sets the active connections.
/// </summary>
/// <value>The active connections.</value>
public List<SessionInfoDto> ActiveConnections { get; set; }
}
}

@ -1,62 +0,0 @@
using MediaBrowser.Common.Net;
using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Logging;
using System.Threading.Tasks;
namespace MediaBrowser.WebDashboard.Api
{
/// <summary>
/// Class DashboardInfoWebSocketListener
/// </summary>
class DashboardInfoWebSocketListener : BasePeriodicWebSocketListener<DashboardInfo, object>
{
/// <summary>
/// Gets the name.
/// </summary>
/// <value>The name.</value>
protected override string Name
{
get { return "DashboardInfo"; }
}
private readonly IServerApplicationHost _appHost;
/// <summary>
/// Gets or sets the task manager.
/// </summary>
/// <value>The task manager.</value>
private readonly ITaskManager _taskManager;
private readonly ISessionManager _sessionManager;
private readonly IDtoService _dtoService;
/// <summary>
/// Initializes a new instance of the <see cref="DashboardInfoWebSocketListener" /> class.
/// </summary>
/// <param name="appHost">The app host.</param>
/// <param name="logger">The logger.</param>
/// <param name="taskManager">The task manager.</param>
/// <param name="sessionManager">The session manager.</param>
public DashboardInfoWebSocketListener(IServerApplicationHost appHost, ILogger logger, ITaskManager taskManager, ISessionManager sessionManager, IDtoService dtoService)
: base(logger)
{
_appHost = appHost;
_taskManager = taskManager;
_sessionManager = sessionManager;
_dtoService = dtoService;
}
/// <summary>
/// Gets the data to send.
/// </summary>
/// <param name="state">The state.</param>
/// <returns>Task{IEnumerable{TaskInfo}}.</returns>
protected override Task<DashboardInfo> GetDataToSend(object state)
{
return Task.FromResult(DashboardService.GetDashboardInfo(_appHost, _taskManager, _sessionManager, _dtoService));
}
}
}

@ -1,16 +1,13 @@
using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.IO; using MediaBrowser.Common.IO;
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Controller; using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Plugins; using MediaBrowser.Controller.Plugins;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Logging; using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Tasks;
using ServiceStack; using ServiceStack;
using ServiceStack.Web;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -18,7 +15,6 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using ServiceStack.Web;
namespace MediaBrowser.WebDashboard.Api namespace MediaBrowser.WebDashboard.Api
{ {
@ -66,14 +62,6 @@ namespace MediaBrowser.WebDashboard.Api
public string V { get; set; } public string V { get; set; }
} }
/// <summary>
/// Class GetDashboardInfo
/// </summary>
[Route("/dashboard/dashboardInfo", "GET")]
public class GetDashboardInfo : IReturn<DashboardInfo>
{
}
/// <summary> /// <summary>
/// Class DashboardService /// Class DashboardService
/// </summary> /// </summary>
@ -97,12 +85,6 @@ namespace MediaBrowser.WebDashboard.Api
/// <value>The request context.</value> /// <value>The request context.</value>
public IRequest Request { get; set; } public IRequest Request { get; set; }
/// <summary>
/// Gets or sets the task manager.
/// </summary>
/// <value>The task manager.</value>
private readonly ITaskManager _taskManager;
/// <summary> /// <summary>
/// The _app host /// The _app host
/// </summary> /// </summary>
@ -113,24 +95,18 @@ namespace MediaBrowser.WebDashboard.Api
/// </summary> /// </summary>
private readonly IServerConfigurationManager _serverConfigurationManager; private readonly IServerConfigurationManager _serverConfigurationManager;
private readonly ISessionManager _sessionManager;
private readonly IDtoService _dtoService;
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="DashboardService" /> class. /// Initializes a new instance of the <see cref="DashboardService" /> class.
/// </summary> /// </summary>
/// <param name="taskManager">The task manager.</param>
/// <param name="appHost">The app host.</param> /// <param name="appHost">The app host.</param>
/// <param name="serverConfigurationManager">The server configuration manager.</param> /// <param name="serverConfigurationManager">The server configuration manager.</param>
/// <param name="sessionManager">The session manager.</param> /// <param name="fileSystem">The file system.</param>
public DashboardService(ITaskManager taskManager, IServerApplicationHost appHost, IServerConfigurationManager serverConfigurationManager, ISessionManager sessionManager, IDtoService dtoService, IFileSystem fileSystem) public DashboardService(IServerApplicationHost appHost, IServerConfigurationManager serverConfigurationManager, IFileSystem fileSystem)
{ {
_taskManager = taskManager;
_appHost = appHost; _appHost = appHost;
_serverConfigurationManager = serverConfigurationManager; _serverConfigurationManager = serverConfigurationManager;
_sessionManager = sessionManager;
_dtoService = dtoService;
_fileSystem = fileSystem; _fileSystem = fileSystem;
} }
@ -163,45 +139,6 @@ namespace MediaBrowser.WebDashboard.Api
return Path.Combine(DashboardUIPath, virtualPath.Replace('/', Path.DirectorySeparatorChar)); return Path.Combine(DashboardUIPath, virtualPath.Replace('/', Path.DirectorySeparatorChar));
} }
/// <summary>
/// Gets the specified request.
/// </summary>
/// <param name="request">The request.</param>
/// <returns>System.Object.</returns>
public object Get(GetDashboardInfo request)
{
var result = GetDashboardInfo(_appHost, _taskManager, _sessionManager, _dtoService);
return ResultFactory.GetOptimizedResult(Request, result);
}
/// <summary>
/// Gets the dashboard info.
/// </summary>
/// <param name="appHost">The app host.</param>
/// <param name="taskManager">The task manager.</param>
/// <param name="connectionManager">The connection manager.</param>
/// <returns>DashboardInfo.</returns>
public static DashboardInfo GetDashboardInfo(IServerApplicationHost appHost,
ITaskManager taskManager,
ISessionManager connectionManager, IDtoService dtoService)
{
var connections = connectionManager.Sessions.Where(i => i.IsActive).ToList();
return new DashboardInfo
{
SystemInfo = appHost.GetSystemInfo(),
RunningTasks = taskManager.ScheduledTasks.Where(i => i.State == TaskState.Running || i.State == TaskState.Cancelling)
.Select(ScheduledTaskHelpers.GetTaskInfo)
.ToList(),
ApplicationUpdateTaskId = taskManager.ScheduledTasks.First(t => t.ScheduledTask.GetType().Name.Equals("SystemUpdateTask", StringComparison.OrdinalIgnoreCase)).Id,
ActiveConnections = connections.Select(dtoService.GetSessionInfoDto).ToList()
};
}
/// <summary> /// <summary>
/// Gets the specified request. /// Gets the specified request.
/// </summary> /// </summary>
@ -473,6 +410,7 @@ namespace MediaBrowser.WebDashboard.Api
"alphapicker.js", "alphapicker.js",
"addpluginpage.js", "addpluginpage.js",
"advancedconfigurationpage.js", "advancedconfigurationpage.js",
"advancedpaths.js",
"advancedserversettings.js", "advancedserversettings.js",
"metadataadvanced.js", "metadataadvanced.js",
"appsplayback.js", "appsplayback.js",

@ -63,9 +63,7 @@
<Link>Properties\SharedVersion.cs</Link> <Link>Properties\SharedVersion.cs</Link>
</Compile> </Compile>
<Compile Include="Api\ConfigurationPageInfo.cs" /> <Compile Include="Api\ConfigurationPageInfo.cs" />
<Compile Include="Api\DashboardInfo.cs" />
<Compile Include="Api\DashboardService.cs" /> <Compile Include="Api\DashboardService.cs" />
<Compile Include="Api\DashboardInfoWebSocketListener.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ServerEntryPoint.cs" /> <Compile Include="ServerEntryPoint.cs" />
</ItemGroup> </ItemGroup>
@ -85,6 +83,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="ApiClient.js" /> <EmbeddedResource Include="ApiClient.js" />
<Content Include="dashboard-ui\advancedpaths.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\advancedserversettings.html"> <Content Include="dashboard-ui\advancedserversettings.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
@ -483,6 +484,9 @@
<Content Include="dashboard-ui\livetvrecordings.html"> <Content Include="dashboard-ui\livetvrecordings.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="dashboard-ui\scripts\advancedpaths.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\advancedserversettings.js"> <Content Include="dashboard-ui\scripts\advancedserversettings.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>

Loading…
Cancel
Save