aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Api
diff options
context:
space:
mode:
Diffstat (limited to 'MediaBrowser.Api')
-rw-r--r--MediaBrowser.Api/BrandingService.cs28
-rw-r--r--MediaBrowser.Api/ConfigurationService.cs7
-rw-r--r--MediaBrowser.Api/Images/ImageService.cs7
-rw-r--r--MediaBrowser.Api/ItemRefreshService.cs22
-rw-r--r--MediaBrowser.Api/Library/LibraryService.cs2
-rw-r--r--MediaBrowser.Api/MediaBrowser.Api.csproj4
-rw-r--r--MediaBrowser.Api/NotificationsService.cs2
-rw-r--r--MediaBrowser.Api/SessionsService.cs12
-rw-r--r--MediaBrowser.Api/Subtitles/SubtitleService.cs (renamed from MediaBrowser.Api/Library/SubtitleService.cs)83
-rw-r--r--MediaBrowser.Api/SystemService.cs70
-rw-r--r--MediaBrowser.Api/UserLibrary/UserLibraryService.cs10
-rw-r--r--MediaBrowser.Api/UserService.cs4
-rw-r--r--MediaBrowser.Api/WebSocket/LogFileWebSocketListener.cs149
13 files changed, 191 insertions, 209 deletions
diff --git a/MediaBrowser.Api/BrandingService.cs b/MediaBrowser.Api/BrandingService.cs
new file mode 100644
index 000000000..4b49b411a
--- /dev/null
+++ b/MediaBrowser.Api/BrandingService.cs
@@ -0,0 +1,28 @@
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Model.Branding;
+using ServiceStack;
+
+namespace MediaBrowser.Api
+{
+ [Route("/Branding/Configuration", "GET", Summary = "Gets branding configuration")]
+ public class GetBrandingOptions : IReturn<BrandingOptions>
+ {
+ }
+
+ public class BrandingService : BaseApiService
+ {
+ private readonly IConfigurationManager _config;
+
+ public BrandingService(IConfigurationManager config)
+ {
+ _config = config;
+ }
+
+ public object Get(GetBrandingOptions request)
+ {
+ var result = _config.GetConfiguration<BrandingOptions>("branding");
+
+ return ToOptimizedResult(result);
+ }
+ }
+}
diff --git a/MediaBrowser.Api/ConfigurationService.cs b/MediaBrowser.Api/ConfigurationService.cs
index 39fcc50d8..291deb3b0 100644
--- a/MediaBrowser.Api/ConfigurationService.cs
+++ b/MediaBrowser.Api/ConfigurationService.cs
@@ -4,6 +4,7 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Serialization;
@@ -27,6 +28,7 @@ namespace MediaBrowser.Api
}
[Route("/System/Configuration/{Key}", "GET", Summary = "Gets a named configuration")]
+ [Authenticated]
public class GetNamedConfiguration
{
[ApiMember(Name = "Key", Description = "Key", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
@@ -37,11 +39,13 @@ namespace MediaBrowser.Api
/// Class UpdateConfiguration
/// </summary>
[Route("/System/Configuration", "POST", Summary = "Updates application configuration")]
+ [Authenticated]
public class UpdateConfiguration : ServerConfiguration, IReturnVoid
{
}
[Route("/System/Configuration/{Key}", "POST", Summary = "Updates named configuration")]
+ [Authenticated]
public class UpdateNamedConfiguration : IReturnVoid, IRequiresRequestStream
{
[ApiMember(Name = "Key", Description = "Key", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
@@ -51,18 +55,21 @@ namespace MediaBrowser.Api
}
[Route("/System/Configuration/MetadataOptions/Default", "GET", Summary = "Gets a default MetadataOptions object")]
+ [Authenticated]
public class GetDefaultMetadataOptions : IReturn<MetadataOptions>
{
}
[Route("/System/Configuration/MetadataPlugins", "GET", Summary = "Gets all available metadata plugins")]
+ [Authenticated]
public class GetMetadataPlugins : IReturn<List<MetadataPluginSummary>>
{
}
[Route("/System/Configuration/VideoImageExtraction", "POST", Summary = "Updates image extraction for all types")]
+ [Authenticated]
public class UpdateVideoImageExtraction : IReturnVoid
{
public bool Enabled { get; set; }
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index 4f8c348bb..deaefe019 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -3,6 +3,7 @@ using MediaBrowser.Common.IO;
using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Drawing;
@@ -26,6 +27,7 @@ namespace MediaBrowser.Api.Images
/// </summary>
[Route("/Items/{Id}/Images", "GET")]
[Api(Description = "Gets information about an item's images")]
+ [Authenticated]
public class GetItemImageInfos : IReturn<List<ImageInfo>>
{
/// <summary>
@@ -56,6 +58,7 @@ namespace MediaBrowser.Api.Images
/// </summary>
[Route("/Items/{Id}/Images/{Type}/{Index}/Index", "POST")]
[Api(Description = "Updates the index for an item image")]
+ [Authenticated]
public class UpdateItemImageIndex : IReturnVoid
{
/// <summary>
@@ -137,6 +140,7 @@ namespace MediaBrowser.Api.Images
[Route("/Items/{Id}/Images/{Type}", "DELETE")]
[Route("/Items/{Id}/Images/{Type}/{Index}", "DELETE")]
[Api(Description = "Deletes an item image")]
+ [Authenticated]
public class DeleteItemImage : DeleteImageRequest, IReturnVoid
{
/// <summary>
@@ -153,6 +157,7 @@ namespace MediaBrowser.Api.Images
[Route("/Users/{Id}/Images/{Type}", "DELETE")]
[Route("/Users/{Id}/Images/{Type}/{Index}", "DELETE")]
[Api(Description = "Deletes a user image")]
+ [Authenticated]
public class DeleteUserImage : DeleteImageRequest, IReturnVoid
{
/// <summary>
@@ -169,6 +174,7 @@ namespace MediaBrowser.Api.Images
[Route("/Users/{Id}/Images/{Type}", "POST")]
[Route("/Users/{Id}/Images/{Type}/{Index}", "POST")]
[Api(Description = "Posts a user image")]
+ [Authenticated]
public class PostUserImage : DeleteImageRequest, IRequiresRequestStream, IReturnVoid
{
/// <summary>
@@ -191,6 +197,7 @@ namespace MediaBrowser.Api.Images
[Route("/Items/{Id}/Images/{Type}", "POST")]
[Route("/Items/{Id}/Images/{Type}/{Index}", "POST")]
[Api(Description = "Posts an item image")]
+ [Authenticated]
public class PostItemImage : DeleteImageRequest, IRequiresRequestStream, IReturnVoid
{
/// <summary>
diff --git a/MediaBrowser.Api/ItemRefreshService.cs b/MediaBrowser.Api/ItemRefreshService.cs
index b95e18a0d..993b69601 100644
--- a/MediaBrowser.Api/ItemRefreshService.cs
+++ b/MediaBrowser.Api/ItemRefreshService.cs
@@ -13,10 +13,16 @@ namespace MediaBrowser.Api
{
public class BaseRefreshRequest : IReturnVoid
{
- [ApiMember(Name = "Forced", Description = "Indicates if a normal or forced refresh should occur.", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "POST")]
- public bool Forced { get; set; }
+ [ApiMember(Name = "MetadataRefreshMode", Description = "Specifies the metadata refresh mode", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "POST")]
+ public MetadataRefreshMode MetadataRefreshMode { get; set; }
- [ApiMember(Name = "ReplaceAllImages", Description = "Determines if images should be replaced during the refresh.", IsRequired = true, DataType = "boolean", ParameterType = "query", Verb = "POST")]
+ [ApiMember(Name = "ImageRefreshMode", Description = "Specifies the image refresh mode", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "POST")]
+ public ImageRefreshMode ImageRefreshMode { get; set; }
+
+ [ApiMember(Name = "ReplaceAllMetadata", Description = "Determines if metadata should be replaced. Only applicable if mode is FullRefresh", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "POST")]
+ public bool ReplaceAllMetadata { get; set; }
+
+ [ApiMember(Name = "ReplaceAllImages", Description = "Determines if images should be replaced. Only applicable if mode is FullRefresh", IsRequired = false, DataType = "boolean", ParameterType = "query", Verb = "POST")]
public bool ReplaceAllImages { get; set; }
}
@@ -93,7 +99,7 @@ namespace MediaBrowser.Api
private async Task RefreshItem(RefreshItem request, BaseItem item)
{
var options = GetRefreshOptions(request);
-
+
try
{
await item.RefreshMetadata(options, CancellationToken.None).ConfigureAwait(false);
@@ -148,10 +154,10 @@ namespace MediaBrowser.Api
{
return new MetadataRefreshOptions
{
- MetadataRefreshMode = MetadataRefreshMode.FullRefresh,
- ImageRefreshMode = ImageRefreshMode.FullRefresh,
- ReplaceAllMetadata = request.Forced,
- ReplaceAllImages = request.ReplaceAllImages
+ MetadataRefreshMode = request.MetadataRefreshMode,
+ ImageRefreshMode = request.ImageRefreshMode,
+ ReplaceAllImages = request.ReplaceAllImages,
+ ReplaceAllMetadata = request.ReplaceAllMetadata
};
}
}
diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs
index 77a714755..10aa23126 100644
--- a/MediaBrowser.Api/Library/LibraryService.cs
+++ b/MediaBrowser.Api/Library/LibraryService.cs
@@ -5,6 +5,7 @@ using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.Movies;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dto;
@@ -226,6 +227,7 @@ namespace MediaBrowser.Api.Library
/// <summary>
/// Class LibraryService
/// </summary>
+ [Authenticated]
public class LibraryService : BaseApiService
{
/// <summary>
diff --git a/MediaBrowser.Api/MediaBrowser.Api.csproj b/MediaBrowser.Api/MediaBrowser.Api.csproj
index a68966b33..ca2887d19 100644
--- a/MediaBrowser.Api/MediaBrowser.Api.csproj
+++ b/MediaBrowser.Api/MediaBrowser.Api.csproj
@@ -65,11 +65,12 @@
<Compile Include="..\SharedVersion.cs">
<Link>Properties\SharedVersion.cs</Link>
</Compile>
+ <Compile Include="BrandingService.cs" />
<Compile Include="ChannelService.cs" />
<Compile Include="Dlna\DlnaServerService.cs" />
<Compile Include="Dlna\DlnaService.cs" />
<Compile Include="Library\ChapterService.cs" />
- <Compile Include="Library\SubtitleService.cs" />
+ <Compile Include="Subtitles\SubtitleService.cs" />
<Compile Include="Movies\CollectionService.cs" />
<Compile Include="Music\AlbumsService.cs" />
<Compile Include="AppThemeService.cs" />
@@ -139,7 +140,6 @@
<Compile Include="UserService.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="VideosService.cs" />
- <Compile Include="WebSocket\LogFileWebSocketListener.cs" />
<Compile Include="WebSocket\SessionInfoWebSocketListener.cs" />
<Compile Include="WebSocket\SystemInfoWebSocketListener.cs" />
</ItemGroup>
diff --git a/MediaBrowser.Api/NotificationsService.cs b/MediaBrowser.Api/NotificationsService.cs
index 28edb61dd..51a080106 100644
--- a/MediaBrowser.Api/NotificationsService.cs
+++ b/MediaBrowser.Api/NotificationsService.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Notifications;
using MediaBrowser.Model.Notifications;
using ServiceStack;
@@ -82,6 +83,7 @@ namespace MediaBrowser.Api
public string Ids { get; set; }
}
+ [Authenticated]
public class NotificationsService : BaseApiService
{
private readonly INotificationsRepository _notificationsRepo;
diff --git a/MediaBrowser.Api/SessionsService.cs b/MediaBrowser.Api/SessionsService.cs
index 00c307a18..f4651601b 100644
--- a/MediaBrowser.Api/SessionsService.cs
+++ b/MediaBrowser.Api/SessionsService.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Session;
using ServiceStack;
@@ -14,6 +15,7 @@ namespace MediaBrowser.Api
/// Class GetSessions
/// </summary>
[Route("/Sessions", "GET", Summary = "Gets a list of sessions")]
+ [Authenticated]
public class GetSessions : IReturn<List<SessionInfoDto>>
{
[ApiMember(Name = "ControllableByUserId", Description = "Optional. Filter by sessions that a given user is allowed to remote control.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
@@ -27,6 +29,7 @@ namespace MediaBrowser.Api
/// Class DisplayContent
/// </summary>
[Route("/Sessions/{Id}/Viewing", "POST", Summary = "Instructs a session to browse to an item or view")]
+ [Authenticated]
public class DisplayContent : IReturnVoid
{
/// <summary>
@@ -59,6 +62,7 @@ namespace MediaBrowser.Api
}
[Route("/Sessions/{Id}/Playing", "POST", Summary = "Instructs a session to play an item")]
+ [Authenticated]
public class Play : IReturnVoid
{
/// <summary>
@@ -91,6 +95,7 @@ namespace MediaBrowser.Api
}
[Route("/Sessions/{Id}/Playing/{Command}", "POST", Summary = "Issues a playstate command to a client")]
+ [Authenticated]
public class SendPlaystateCommand : IReturnVoid
{
/// <summary>
@@ -115,6 +120,7 @@ namespace MediaBrowser.Api
}
[Route("/Sessions/{Id}/System/{Command}", "POST", Summary = "Issues a system command to a client")]
+ [Authenticated]
public class SendSystemCommand : IReturnVoid
{
/// <summary>
@@ -133,6 +139,7 @@ namespace MediaBrowser.Api
}
[Route("/Sessions/{Id}/Command/{Command}", "POST", Summary = "Issues a system command to a client")]
+ [Authenticated]
public class SendGeneralCommand : IReturnVoid
{
/// <summary>
@@ -151,6 +158,7 @@ namespace MediaBrowser.Api
}
[Route("/Sessions/{Id}/Command", "POST", Summary = "Issues a system command to a client")]
+ [Authenticated]
public class SendFullGeneralCommand : GeneralCommand, IReturnVoid
{
/// <summary>
@@ -162,6 +170,7 @@ namespace MediaBrowser.Api
}
[Route("/Sessions/{Id}/Message", "POST", Summary = "Issues a command to a client to display a message to the user")]
+ [Authenticated]
public class SendMessageCommand : IReturnVoid
{
/// <summary>
@@ -182,6 +191,7 @@ namespace MediaBrowser.Api
}
[Route("/Sessions/{Id}/Users/{UserId}", "POST", Summary = "Adds an additional user to a session")]
+ [Authenticated]
public class AddUserToSession : IReturnVoid
{
[ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
@@ -192,6 +202,7 @@ namespace MediaBrowser.Api
}
[Route("/Sessions/{Id}/Users/{UserId}", "DELETE", Summary = "Removes an additional user from a session")]
+ [Authenticated]
public class RemoveUserFromSession : IReturnVoid
{
[ApiMember(Name = "Id", Description = "Session Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
@@ -202,7 +213,6 @@ namespace MediaBrowser.Api
}
[Route("/Sessions/Capabilities", "POST", Summary = "Updates capabilities for a device")]
- [Route("/Sessions/{Id}/Capabilities", "POST", Summary = "Updates capabilities for a device")]
public class PostCapabilities : IReturnVoid
{
/// <summary>
diff --git a/MediaBrowser.Api/Library/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs
index 4fc3e00c0..3e692cb22 100644
--- a/MediaBrowser.Api/Library/SubtitleService.cs
+++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs
@@ -1,4 +1,6 @@
-using MediaBrowser.Controller.Entities;
+using System.IO;
+using System.Linq;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Net;
@@ -9,37 +11,13 @@ using MediaBrowser.Model.Providers;
using ServiceStack;
using System;
using System.Collections.Generic;
-using System.IO;
-using System.Linq;
using System.Threading;
using System.Threading.Tasks;
-namespace MediaBrowser.Api.Library
+namespace MediaBrowser.Api.Subtitles
{
- [Route("/Videos/{Id}/{MediaSourceId}/Subtitles/{Index}/Stream.{Format}", "GET", Summary = "Gets subtitles in a specified format (vtt).")]
- public class GetSubtitle
- {
- /// <summary>
- /// Gets or sets the id.
- /// </summary>
- /// <value>The id.</value>
- [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Id { get; set; }
-
- [ApiMember(Name = "MediaSourceId", Description = "MediaSourceId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string MediaSourceId { get; set; }
-
- [ApiMember(Name = "Index", Description = "The subtitle stream index", IsRequired = true, DataType = "int", ParameterType = "path", Verb = "GET")]
- public int Index { get; set; }
-
- [ApiMember(Name = "Format", Description = "Format", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public string Format { get; set; }
-
- [ApiMember(Name = "StartPositionTicks", Description = "StartPositionTicks", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
- public long StartPositionTicks { get; set; }
- }
-
[Route("/Videos/{Id}/Subtitles/{Index}", "DELETE", Summary = "Deletes an external subtitle file")]
+ [Authenticated]
public class DeleteSubtitle
{
/// <summary>
@@ -54,6 +32,7 @@ namespace MediaBrowser.Api.Library
}
[Route("/Items/{Id}/RemoteSearch/Subtitles/{Language}", "GET")]
+ [Authenticated]
public class SearchRemoteSubtitles : IReturn<List<RemoteSubtitleInfo>>
{
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
@@ -64,6 +43,7 @@ namespace MediaBrowser.Api.Library
}
[Route("/Items/{Id}/RemoteSearch/Subtitles/Providers", "GET")]
+ [Authenticated]
public class GetSubtitleProviders : IReturn<List<SubtitleProviderInfo>>
{
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
@@ -71,6 +51,7 @@ namespace MediaBrowser.Api.Library
}
[Route("/Items/{Id}/RemoteSearch/Subtitles/{SubtitleId}", "POST")]
+ [Authenticated]
public class DownloadRemoteSubtitles : IReturnVoid
{
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
@@ -81,13 +62,36 @@ namespace MediaBrowser.Api.Library
}
[Route("/Providers/Subtitles/Subtitles/{Id}", "GET")]
+ [Authenticated]
public class GetRemoteSubtitles : IReturnVoid
{
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
}
- [Authenticated]
+ [Route("/Videos/{Id}/{MediaSourceId}/Subtitles/{Index}/Stream.{Format}", "GET", Summary = "Gets subtitles in a specified format (vtt).")]
+ public class GetSubtitle
+ {
+ /// <summary>
+ /// Gets or sets the id.
+ /// </summary>
+ /// <value>The id.</value>
+ [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ public string Id { get; set; }
+
+ [ApiMember(Name = "MediaSourceId", Description = "MediaSourceId", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ public string MediaSourceId { get; set; }
+
+ [ApiMember(Name = "Index", Description = "The subtitle stream index", IsRequired = true, DataType = "int", ParameterType = "path", Verb = "GET")]
+ public int Index { get; set; }
+
+ [ApiMember(Name = "Format", Description = "Format", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ public string Format { get; set; }
+
+ [ApiMember(Name = "StartPositionTicks", Description = "StartPositionTicks", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public long StartPositionTicks { get; set; }
+ }
+
public class SubtitleService : BaseApiService
{
private readonly ILibraryManager _libraryManager;
@@ -101,14 +105,6 @@ namespace MediaBrowser.Api.Library
_subtitleEncoder = subtitleEncoder;
}
- public object Get(SearchRemoteSubtitles request)
- {
- var video = (Video)_libraryManager.GetItemById(request.Id);
-
- var response = _subtitleManager.SearchSubtitles(video, request.Language, CancellationToken.None).Result;
-
- return ToOptimizedResult(response);
- }
public object Get(GetSubtitle request)
{
if (string.IsNullOrEmpty(request.Format))
@@ -131,14 +127,23 @@ namespace MediaBrowser.Api.Library
private async Task<Stream> GetSubtitles(GetSubtitle request)
{
- return await _subtitleEncoder.GetSubtitles(request.Id,
- request.MediaSourceId,
- request.Index,
+ return await _subtitleEncoder.GetSubtitles(request.Id,
+ request.MediaSourceId,
+ request.Index,
request.Format,
request.StartPositionTicks,
CancellationToken.None).ConfigureAwait(false);
}
+ public object Get(SearchRemoteSubtitles request)
+ {
+ var video = (Video)_libraryManager.GetItemById(request.Id);
+
+ var response = _subtitleManager.SearchSubtitles(video, request.Language, CancellationToken.None).Result;
+
+ return ToOptimizedResult(response);
+ }
+
public void Delete(DeleteSubtitle request)
{
var task = _subtitleManager.DeleteSubtitles(request.Id, request.Index);
diff --git a/MediaBrowser.Api/SystemService.cs b/MediaBrowser.Api/SystemService.cs
index 2f0741434..6f2e83a79 100644
--- a/MediaBrowser.Api/SystemService.cs
+++ b/MediaBrowser.Api/SystemService.cs
@@ -1,6 +1,12 @@
-using MediaBrowser.Controller;
+using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller;
+using MediaBrowser.Controller.Net;
using MediaBrowser.Model.System;
using ServiceStack;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
using System.Threading.Tasks;
namespace MediaBrowser.Api
@@ -18,15 +24,30 @@ namespace MediaBrowser.Api
/// Class RestartApplication
/// </summary>
[Route("/System/Restart", "POST", Summary = "Restarts the application, if needed")]
+ [Authenticated]
public class RestartApplication
{
}
[Route("/System/Shutdown", "POST", Summary = "Shuts down the application")]
+ [Authenticated]
public class ShutdownApplication
{
}
+ [Route("/System/Logs", "GET", Summary = "Gets a list of available server log files")]
+ [Authenticated]
+ public class GetServerLogs : IReturn<List<LogFile>>
+ {
+ }
+
+ [Route("/System/Logs/Log", "GET", Summary = "Gets a log file")]
+ public class GetLogFile
+ {
+ [ApiMember(Name = "Name", Description = "The log file name.", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET", AllowMultiple = true)]
+ public string Name { get; set; }
+ }
+
/// <summary>
/// Class SystemInfoService
/// </summary>
@@ -36,16 +57,59 @@ namespace MediaBrowser.Api
/// The _app host
/// </summary>
private readonly IServerApplicationHost _appHost;
-
+ private readonly IApplicationPaths _appPaths;
+ private readonly IFileSystem _fileSystem;
/// <summary>
/// Initializes a new instance of the <see cref="SystemService" /> class.
/// </summary>
/// <param name="appHost">The app host.</param>
/// <exception cref="System.ArgumentNullException">jsonSerializer</exception>
- public SystemService(IServerApplicationHost appHost)
+ public SystemService(IServerApplicationHost appHost, IApplicationPaths appPaths, IFileSystem fileSystem)
{
_appHost = appHost;
+ _appPaths = appPaths;
+ _fileSystem = fileSystem;
+ }
+
+ public object Get(GetServerLogs request)
+ {
+ List<FileInfo> files;
+
+ try
+ {
+ files = new DirectoryInfo(_appPaths.LogDirectoryPath)
+ .EnumerateFiles("*", SearchOption.AllDirectories)
+ .Where(i => string.Equals(i.Extension, ".txt", System.StringComparison.OrdinalIgnoreCase))
+ .ToList();
+ }
+ catch (DirectoryNotFoundException)
+ {
+ files = new List<FileInfo>();
+ }
+
+ var result = files.Select(i => new LogFile
+ {
+ DateCreated = _fileSystem.GetCreationTimeUtc(i),
+ DateModified = _fileSystem.GetLastWriteTimeUtc(i),
+ Name = i.Name,
+ Size = i.Length
+
+ }).OrderByDescending(i => i.DateModified)
+ .ThenByDescending(i => i.DateCreated)
+ .ThenBy(i => i.Name)
+ .ToList();
+
+ return ToOptimizedResult(result);
+ }
+
+ public object Get(GetLogFile request)
+ {
+ var file = new DirectoryInfo(_appPaths.LogDirectoryPath)
+ .EnumerateFiles("*", SearchOption.AllDirectories)
+ .First(i => string.Equals(i.Name, request.Name, System.StringComparison.OrdinalIgnoreCase));
+
+ return ResultFactory.GetStaticFileResult(Request, file.FullName, FileShare.ReadWrite);
}
/// <summary>
diff --git a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
index d1767e7fd..55cdc8681 100644
--- a/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
+++ b/MediaBrowser.Api/UserLibrary/UserLibraryService.cs
@@ -717,9 +717,7 @@ namespace MediaBrowser.Api.UserLibrary
await _userDataRepository.SaveUserData(user.Id, item, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None).ConfigureAwait(false);
- data = _userDataRepository.GetUserData(user.Id, key);
-
- return _dtoService.GetUserItemDataDto(data);
+ return _userDataRepository.GetUserDataDto(item, user);
}
/// <summary>
@@ -766,9 +764,7 @@ namespace MediaBrowser.Api.UserLibrary
await _userDataRepository.SaveUserData(user.Id, item, data, UserDataSaveReason.UpdateUserRating, CancellationToken.None).ConfigureAwait(false);
- data = _userDataRepository.GetUserData(user.Id, key);
-
- return _dtoService.GetUserItemDataDto(data);
+ return _userDataRepository.GetUserDataDto(item, user);
}
/// <summary>
@@ -936,7 +932,7 @@ namespace MediaBrowser.Api.UserLibrary
await item.MarkUnplayed(user, _userDataRepository).ConfigureAwait(false);
}
- return _dtoService.GetUserItemDataDto(_userDataRepository.GetUserData(user.Id, item.GetUserDataKey()));
+ return _userDataRepository.GetUserDataDto(item, user);
}
}
}
diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs
index 64d1fcb34..cda489c94 100644
--- a/MediaBrowser.Api/UserService.cs
+++ b/MediaBrowser.Api/UserService.cs
@@ -51,6 +51,7 @@ namespace MediaBrowser.Api
/// Class DeleteUser
/// </summary>
[Route("/Users/{Id}", "DELETE", Summary = "Deletes a user")]
+ [Authenticated]
public class DeleteUser : IReturnVoid
{
/// <summary>
@@ -107,6 +108,7 @@ namespace MediaBrowser.Api
/// Class UpdateUserPassword
/// </summary>
[Route("/Users/{Id}/Password", "POST", Summary = "Updates a user's password")]
+ [Authenticated]
public class UpdateUserPassword : IReturnVoid
{
/// <summary>
@@ -138,6 +140,7 @@ namespace MediaBrowser.Api
/// Class UpdateUser
/// </summary>
[Route("/Users/{Id}", "POST", Summary = "Updates a user")]
+ [Authenticated]
public class UpdateUser : UserDto, IReturnVoid
{
}
@@ -146,6 +149,7 @@ namespace MediaBrowser.Api
/// Class CreateUser
/// </summary>
[Route("/Users", "POST", Summary = "Creates a user")]
+ [Authenticated]
public class CreateUser : UserDto, IReturn<UserDto>
{
}
diff --git a/MediaBrowser.Api/WebSocket/LogFileWebSocketListener.cs b/MediaBrowser.Api/WebSocket/LogFileWebSocketListener.cs
deleted file mode 100644
index 46dabb042..000000000
--- a/MediaBrowser.Api/WebSocket/LogFileWebSocketListener.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Common.Net;
-using MediaBrowser.Controller.IO;
-using MediaBrowser.Model.Logging;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Threading.Tasks;
-
-namespace MediaBrowser.Api.WebSocket
-{
- /// <summary>
- /// Class ScheduledTasksWebSocketListener
- /// </summary>
- public class LogFileWebSocketListener : BasePeriodicWebSocketListener<IEnumerable<string>, LogFileWebSocketState>
- {
- /// <summary>
- /// Gets the name.
- /// </summary>
- /// <value>The name.</value>
- protected override string Name
- {
- get { return "LogFile"; }
- }
-
- /// <summary>
- /// The _kernel
- /// </summary>
- private readonly ILogManager _logManager;
- private readonly IFileSystem _fileSystem;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="LogFileWebSocketListener" /> class.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="logManager">The log manager.</param>
- public LogFileWebSocketListener(ILogger logger, ILogManager logManager, IFileSystem fileSystem)
- : base(logger)
- {
- _logManager = logManager;
- _fileSystem = fileSystem;
- _logManager.LoggerLoaded += kernel_LoggerLoaded;
- }
-
- /// <summary>
- /// Gets the data to send.
- /// </summary>
- /// <param name="state">The state.</param>
- /// <returns>IEnumerable{System.String}.</returns>
- protected override async Task<IEnumerable<string>> GetDataToSend(LogFileWebSocketState state)
- {
- if (!string.Equals(_logManager.LogFilePath, state.LastLogFilePath))
- {
- state.LastLogFilePath = _logManager.LogFilePath;
- state.StartLine = 0;
- }
-
- var lines = await GetLogLines(state.LastLogFilePath, state.StartLine, _fileSystem).ConfigureAwait(false);
-
- state.StartLine += lines.Count;
-
- return lines;
- }
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources.
- /// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected override void Dispose(bool dispose)
- {
- if (dispose)
- {
- _logManager.LoggerLoaded -= kernel_LoggerLoaded;
- }
- base.Dispose(dispose);
- }
-
- /// <summary>
- /// Handles the LoggerLoaded event of the kernel control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
- void kernel_LoggerLoaded(object sender, EventArgs e)
- {
- // Reset the startline for each connection whenever the logger reloads
- lock (ActiveConnections)
- {
- foreach (var connection in ActiveConnections)
- {
- connection.Item4.StartLine = 0;
- }
- }
- }
-
- /// <summary>
- /// Gets the log lines.
- /// </summary>
- /// <param name="logFilePath">The log file path.</param>
- /// <param name="startLine">The start line.</param>
- /// <returns>Task{IEnumerable{System.String}}.</returns>
- internal static async Task<List<string>> GetLogLines(string logFilePath, int startLine, IFileSystem fileSystem)
- {
- var lines = new List<string>();
-
- using (var fs = fileSystem.GetFileStream(logFilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
- {
- using (var reader = new StreamReader(fs))
- {
- while (!reader.EndOfStream)
- {
- var line = await reader.ReadLineAsync().ConfigureAwait(false);
-
- if (line.IndexOf("Info -", StringComparison.OrdinalIgnoreCase) != -1 ||
- line.IndexOf("Warn -", StringComparison.OrdinalIgnoreCase) != -1 ||
- line.IndexOf("Error -", StringComparison.OrdinalIgnoreCase) != -1)
- {
- lines.Add(line);
- }
- }
- }
- }
-
- if (startLine > 0)
- {
- lines = lines.Skip(startLine).ToList();
- }
-
- return lines;
- }
- }
-
- /// <summary>
- /// Class LogFileWebSocketState
- /// </summary>
- public class LogFileWebSocketState : WebSocketListenerState
- {
- /// <summary>
- /// Gets or sets the last log file path.
- /// </summary>
- /// <value>The last log file path.</value>
- public string LastLogFilePath { get; set; }
- /// <summary>
- /// Gets or sets the start line.
- /// </summary>
- /// <value>The start line.</value>
- public int StartLine { get; set; }
- }
-}