mirror of
https://github.com/Radarr/Radarr.git
synced 2024-08-17 15:59:36 +02:00
added /logs
This commit is contained in:
parent
fc7d4536ac
commit
9160343a51
@ -8,6 +8,7 @@
|
||||
using NzbDrone.Api.Episodes;
|
||||
using NzbDrone.Api.History;
|
||||
using NzbDrone.Api.Indexers;
|
||||
using NzbDrone.Api.Logs;
|
||||
using NzbDrone.Api.Mapping;
|
||||
using NzbDrone.Api.Qualities;
|
||||
using NzbDrone.Api.RootFolders;
|
||||
@ -15,6 +16,7 @@
|
||||
using NzbDrone.Api.Update;
|
||||
using NzbDrone.Core.DecisionEngine;
|
||||
using NzbDrone.Core.Indexers;
|
||||
using NzbDrone.Core.Instrumentation;
|
||||
using NzbDrone.Core.Organizer;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
@ -40,6 +42,7 @@ public class ResourceMappingFixture : TestBase
|
||||
[TestCase(typeof(UpdatePackage), typeof(UpdateResource))]
|
||||
[TestCase(typeof(QualityProfile), typeof(QualityProfileResource))]
|
||||
[TestCase(typeof(Quality), typeof(QualityResource))]
|
||||
[TestCase(typeof(Log), typeof(LogResource))]
|
||||
public void matching_fields(Type modelType, Type resourceType)
|
||||
{
|
||||
MappingValidation.ValidateMapping(modelType, resourceType);
|
||||
|
25
NzbDrone.Api/Logs/LogModule.cs
Normal file
25
NzbDrone.Api/Logs/LogModule.cs
Normal file
@ -0,0 +1,25 @@
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.History;
|
||||
using NzbDrone.Core.Instrumentation;
|
||||
using NzbDrone.Api.Mapping;
|
||||
|
||||
namespace NzbDrone.Api.Logs
|
||||
{
|
||||
public class LogModule : NzbDroneRestModule<LogResource>
|
||||
{
|
||||
private readonly ILogService _logService;
|
||||
private readonly IHistoryService _historyService;
|
||||
|
||||
public LogModule(ILogService logService)
|
||||
{
|
||||
_logService = logService;
|
||||
GetResourcePaged = GetLogs;
|
||||
}
|
||||
|
||||
private PagingResource<LogResource> GetLogs(PagingResource<LogResource> pagingResource)
|
||||
{
|
||||
var pageSpec = pagingResource.InjectTo<PagingSpec<Log>>();
|
||||
return ApplyToPage(_logService.Paged, pageSpec);
|
||||
}
|
||||
}
|
||||
}
|
16
NzbDrone.Api/Logs/LogResource.cs
Normal file
16
NzbDrone.Api/Logs/LogResource.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using NzbDrone.Api.REST;
|
||||
|
||||
namespace NzbDrone.Api.Logs
|
||||
{
|
||||
public class LogResource : RestResource
|
||||
{
|
||||
public DateTime Time { get; set; }
|
||||
public String Exception { get; set; }
|
||||
public String ExceptionType { get; set; }
|
||||
public String Level { get; set; }
|
||||
public String Logger { get; set; }
|
||||
public String Message { get; set; }
|
||||
public String Method { get; set; }
|
||||
}
|
||||
}
|
@ -115,6 +115,8 @@
|
||||
<Compile Include="Indexers\IndexerResource.cs" />
|
||||
<Compile Include="Indexers\ReleaseModule.cs" />
|
||||
<Compile Include="Extensions\LazyExtensions.cs" />
|
||||
<Compile Include="Logs\LogModule.cs" />
|
||||
<Compile Include="Logs\LogResource.cs" />
|
||||
<Compile Include="Mapping\CloneInjection.cs" />
|
||||
<Compile Include="Mapping\MappingValidation.cs" />
|
||||
<Compile Include="Mapping\ResourceMappingException.cs" />
|
||||
|
@ -195,21 +195,25 @@ private PagingResource<TResource> ReadPagingResourceFromRequest()
|
||||
Int32.TryParse(Request.Query.Page.ToString(), out page);
|
||||
if (page == 0) page = 1;
|
||||
|
||||
var sortKey = Request.Query.SortKey.ToString();
|
||||
if (String.IsNullOrEmpty(sortKey)) sortKey = "AirDate";
|
||||
|
||||
var sortDirection = Request.Query.SortDir.ToString()
|
||||
.Equals("Asc", StringComparison.InvariantCultureIgnoreCase)
|
||||
? SortDirection.Ascending
|
||||
: SortDirection.Descending;
|
||||
|
||||
var pagingResource = new PagingResource<TResource>
|
||||
{
|
||||
PageSize = pageSize,
|
||||
Page = page,
|
||||
SortKey = sortKey,
|
||||
SortDirection = sortDirection
|
||||
};
|
||||
{
|
||||
PageSize = pageSize,
|
||||
Page = page,
|
||||
};
|
||||
|
||||
if (Request.Query.SortKey != null)
|
||||
{
|
||||
pagingResource.SortKey = Request.Query.SortKey.ToString();
|
||||
|
||||
if (Request.Query.SortDir != null)
|
||||
{
|
||||
pagingResource.SortDirection = Request.Query.SortDir.ToString()
|
||||
.Equals("Asc", StringComparison.InvariantCultureIgnoreCase)
|
||||
? SortDirection.Ascending
|
||||
: SortDirection.Descending;
|
||||
}
|
||||
}
|
||||
|
||||
return pagingResource;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ namespace NzbDrone.Core.Datastore
|
||||
void DeleteMany(IEnumerable<int> ids);
|
||||
void SetFields(TModel model, params Expression<Func<TModel, object>>[] properties);
|
||||
TModel Single();
|
||||
PagingSpec<TModel> GetPaged(PagingSpec<TModel> pagingSpec);
|
||||
}
|
||||
|
||||
|
||||
@ -198,6 +199,21 @@ public void SetFields(TModel model, params Expression<Func<TModel, object>>[] pr
|
||||
}
|
||||
|
||||
|
||||
public virtual PagingSpec<TModel> GetPaged(PagingSpec<TModel> pagingSpec)
|
||||
{
|
||||
var pagingQuery = Query.OrderBy(pagingSpec.OrderByClause(), pagingSpec.ToSortDirection())
|
||||
.Skip(pagingSpec.PagingOffset())
|
||||
.Take(pagingSpec.PageSize);
|
||||
|
||||
pagingSpec.Records = pagingQuery.ToList();
|
||||
|
||||
//TODO: Use the same query for count and records
|
||||
pagingSpec.TotalRecords = Count();
|
||||
|
||||
return pagingSpec;
|
||||
}
|
||||
|
||||
|
||||
private void PublishModelEvent(TModel model, RepositoryAction action)
|
||||
{
|
||||
if (PublishModelEvents)
|
||||
|
@ -13,7 +13,6 @@ public interface IHistoryRepository : IBasicRepository<History>
|
||||
{
|
||||
void Trim();
|
||||
List<QualityModel> GetEpisodeHistory(int episodeId);
|
||||
PagingSpec<History> Paged(PagingSpec<History> pagingSpec);
|
||||
}
|
||||
|
||||
public class HistoryRepository : BasicRepository<History>, IHistoryRepository
|
||||
@ -36,7 +35,7 @@ public List<QualityModel> GetEpisodeHistory(int episodeId)
|
||||
return history.Select(h => h.Quality).ToList();
|
||||
}
|
||||
|
||||
public PagingSpec<History> Paged(PagingSpec<History> pagingSpec)
|
||||
public override PagingSpec<History> GetPaged(PagingSpec<History> pagingSpec)
|
||||
{
|
||||
var pagingQuery = Query.Join<History, Series>(JoinType.Inner, h => h.Series, (h, s) => h.SeriesId == s.Id)
|
||||
.Join<History, Episode>(JoinType.Inner, h => h.Episode, (h, e) => h.EpisodeId == e.Id)
|
||||
|
@ -36,7 +36,7 @@ public List<History> All()
|
||||
|
||||
public PagingSpec<History> Paged(PagingSpec<History> pagingSpec)
|
||||
{
|
||||
return _historyRepository.Paged(pagingSpec);
|
||||
return _historyRepository.GetPaged(pagingSpec);
|
||||
}
|
||||
|
||||
public void Purge()
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System.Linq;
|
||||
using NzbDrone.Core.Datastore;
|
||||
|
||||
namespace NzbDrone.Core.Instrumentation
|
||||
{
|
||||
@ -6,6 +7,7 @@ public interface ILogService
|
||||
{
|
||||
void DeleteAll();
|
||||
void Trim();
|
||||
PagingSpec<Log> Paged(PagingSpec<Log> pagingSpec);
|
||||
}
|
||||
|
||||
public class LogService : ILogService
|
||||
@ -26,5 +28,10 @@ public void Trim()
|
||||
{
|
||||
_logRepository.Trim();
|
||||
}
|
||||
|
||||
public PagingSpec<Log> Paged(PagingSpec<Log> pagingSpec)
|
||||
{
|
||||
return _logRepository.GetPaged(pagingSpec);
|
||||
}
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ define(['app',
|
||||
'Series/Details/SeriesDetailsLayout',
|
||||
'Series/EpisodeCollection',
|
||||
'Settings/SettingsLayout',
|
||||
'Logs/Layout',
|
||||
'Missing/MissingLayout',
|
||||
'History/HistoryLayout'],
|
||||
function () {
|
||||
@ -62,11 +63,17 @@ define(['app',
|
||||
NzbDrone.mainRegion.show(new NzbDrone.History.HistoryLayout());
|
||||
},
|
||||
|
||||
logs: function () {
|
||||
this._setTitle('logs');
|
||||
NzbDrone.mainRegion.show(new NzbDrone.Logs.Layout());
|
||||
},
|
||||
|
||||
notFound: function () {
|
||||
this._setTitle('Not Found');
|
||||
NzbDrone.mainRegion.show(new NzbDrone.Shared.NotFoundView(this));
|
||||
},
|
||||
|
||||
|
||||
_setTitle: function (title) {
|
||||
//$('#title-region').html(title);
|
||||
|
||||
|
37
UI/Logs/Collection.js
Normal file
37
UI/Logs/Collection.js
Normal file
@ -0,0 +1,37 @@
|
||||
"use strict";
|
||||
define(['app', 'Logs/Model'], function () {
|
||||
NzbDrone.Logs.Collection = Backbone.PageableCollection.extend({
|
||||
url : NzbDrone.Constants.ApiRoot + '/log',
|
||||
model : NzbDrone.Logs.Model,
|
||||
|
||||
state: {
|
||||
pageSize: 50,
|
||||
sortKey: "time",
|
||||
order: 1
|
||||
},
|
||||
|
||||
queryParams: {
|
||||
totalPages: null,
|
||||
totalRecords: null,
|
||||
pageSize: 'pageSize',
|
||||
sortKey: "sortKey",
|
||||
order: "sortDir",
|
||||
directions: {
|
||||
"-1": "asc",
|
||||
"1": "desc"
|
||||
}
|
||||
},
|
||||
|
||||
parseState: function (resp, queryParams, state) {
|
||||
return {totalRecords: resp.totalRecords};
|
||||
},
|
||||
|
||||
parseRecords: function (resp) {
|
||||
if (resp) {
|
||||
return resp.records;
|
||||
}
|
||||
|
||||
return resp;
|
||||
}
|
||||
});
|
||||
});
|
72
UI/Logs/Layout.js
Normal file
72
UI/Logs/Layout.js
Normal file
@ -0,0 +1,72 @@
|
||||
"use strict";
|
||||
define([
|
||||
'app',
|
||||
'Logs/Collection',
|
||||
'Shared/Toolbar/ToolbarLayout'
|
||||
],
|
||||
function () {
|
||||
NzbDrone.Logs.Layout = Backbone.Marionette.Layout.extend({
|
||||
template: 'Logs/LayoutTemplate',
|
||||
|
||||
regions: {
|
||||
grid : '#x-grid',
|
||||
toolbar: '#x-toolbar',
|
||||
pager : '#x-pager'
|
||||
},
|
||||
|
||||
columns: [
|
||||
{
|
||||
name : 'level',
|
||||
label : 'Level',
|
||||
sortable: true,
|
||||
cell : Backgrid.StringCell
|
||||
},
|
||||
{
|
||||
name : 'logger',
|
||||
label : 'Component',
|
||||
sortable: true,
|
||||
cell : Backgrid.StringCell
|
||||
},
|
||||
{
|
||||
name : 'message',
|
||||
label : 'Message',
|
||||
sortable: false,
|
||||
cell : Backgrid.StringCell
|
||||
},
|
||||
{
|
||||
name : 'time',
|
||||
label: 'Time',
|
||||
cell : Backgrid.DatetimeCell
|
||||
}
|
||||
],
|
||||
|
||||
showTable: function () {
|
||||
|
||||
this.grid.show(new Backgrid.Grid(
|
||||
{
|
||||
row : Backgrid.Row,
|
||||
columns : this.columns,
|
||||
collection: this.collection,
|
||||
className : 'table table-hover'
|
||||
}));
|
||||
|
||||
this.pager.show(new Backgrid.NzbDronePaginator({
|
||||
columns : this.columns,
|
||||
collection: this.collection
|
||||
}));
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
this.collection = new NzbDrone.Logs.Collection();
|
||||
this.collection.fetch();
|
||||
},
|
||||
|
||||
onShow: function () {
|
||||
this.showTable();
|
||||
//this.toolbar.show(new NzbDrone.Shared.Toolbar.ToolbarLayout({right: [ viewButtons], context: this}));
|
||||
}
|
||||
|
||||
})
|
||||
;
|
||||
})
|
||||
;
|
11
UI/Logs/LayoutTemplate.html
Normal file
11
UI/Logs/LayoutTemplate.html
Normal file
@ -0,0 +1,11 @@
|
||||
<div id="x-toolbar"></div>
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<div id="x-grid"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<div id="x-pager"></div>
|
||||
</div>
|
||||
</div>
|
14
UI/Logs/Model.js
Normal file
14
UI/Logs/Model.js
Normal file
@ -0,0 +1,14 @@
|
||||
"use strict";
|
||||
define(['app'], function (app) {
|
||||
NzbDrone.Logs.Model = Backbone.Model.extend({
|
||||
/* mutators: {
|
||||
seasonNumber: function () {
|
||||
return this.get('episode').seasonNumber;
|
||||
},
|
||||
|
||||
paddedEpisodeNumber: function () {
|
||||
return this.get('episode').episodeNumber.pad(2);
|
||||
}
|
||||
}*/
|
||||
});
|
||||
});
|
@ -16,6 +16,7 @@ require(['app', 'Controller'], function (app, controller) {
|
||||
'settings/:action(/:query)' : 'settings',
|
||||
'missing' : 'missing',
|
||||
'history' : 'history',
|
||||
'logs' : 'logs',
|
||||
':whatever' : 'notFound'
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user