mirror of
https://github.com/Sonarr/Sonarr.git
synced 2024-10-30 15:32:31 +01:00
Adding history
This commit is contained in:
parent
6a3d886588
commit
7ab1084437
@ -2,6 +2,7 @@
|
||||
using AutoMapper;
|
||||
using NzbDrone.Api.Calendar;
|
||||
using NzbDrone.Api.Episodes;
|
||||
using NzbDrone.Api.History;
|
||||
using NzbDrone.Api.Missing;
|
||||
using NzbDrone.Api.QualityProfiles;
|
||||
using NzbDrone.Api.QualityType;
|
||||
@ -42,6 +43,10 @@ namespace NzbDrone.Api
|
||||
|
||||
//Episode Paging
|
||||
Mapper.CreateMap<PagingSpec<Episode>, PagingResource<EpisodeResource>>();
|
||||
|
||||
//History
|
||||
Mapper.CreateMap<Core.History.History, HistoryResource>();
|
||||
Mapper.CreateMap<PagingSpec<Core.History.History>, PagingResource<HistoryResource>>();
|
||||
}
|
||||
}
|
||||
}
|
81
NzbDrone.Api/History/HistoryModule.cs
Normal file
81
NzbDrone.Api/History/HistoryModule.cs
Normal file
@ -0,0 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using AutoMapper;
|
||||
using Nancy;
|
||||
using NzbDrone.Api.Episodes;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.History;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Api.History
|
||||
{
|
||||
public class HistoryModule : NzbDroneApiModule
|
||||
{
|
||||
private readonly IHistoryService _historyService;
|
||||
|
||||
public HistoryModule(IHistoryService historyService)
|
||||
: base("/history")
|
||||
{
|
||||
_historyService = historyService;
|
||||
Get["/"] = x => GetHistory();
|
||||
}
|
||||
|
||||
private Response GetHistory()
|
||||
{
|
||||
//TODO: common page parsing logic should be done somewhere else
|
||||
|
||||
int pageSize;
|
||||
Int32.TryParse(PrimitiveExtensions.ToNullSafeString(Request.Query.PageSize), out pageSize);
|
||||
if (pageSize == 0) pageSize = 20;
|
||||
|
||||
int page;
|
||||
Int32.TryParse(PrimitiveExtensions.ToNullSafeString(Request.Query.Page), out page);
|
||||
if (page == 0) page = 1;
|
||||
|
||||
var sortKey = PrimitiveExtensions.ToNullSafeString(Request.Query.SortKey)
|
||||
.Equals("SeriesTitle", StringComparison.InvariantCultureIgnoreCase)
|
||||
? "SeriesTitle"
|
||||
: "AirDate";
|
||||
|
||||
var sortDirection = PrimitiveExtensions.ToNullSafeString(Request.Query.SortDir)
|
||||
.Equals("Asc", StringComparison.InvariantCultureIgnoreCase)
|
||||
? ListSortDirection.Ascending
|
||||
: ListSortDirection.Descending;
|
||||
|
||||
var pagingSpec = new PagingSpec<Episode>
|
||||
{
|
||||
Page = page,
|
||||
PageSize = pageSize,
|
||||
SortKey = sortKey,
|
||||
SortDirection = sortDirection
|
||||
};
|
||||
|
||||
var series = new Core.Tv.Series { Title = "30 Rock", TitleSlug = "30-rock" };
|
||||
var episode = new Episode { Title = "Test", SeasonNumber = 1, EpisodeNumber = 5 };
|
||||
|
||||
var result = new PagingSpec<Core.History.History>
|
||||
{
|
||||
Records = new List<Core.History.History>
|
||||
{
|
||||
new Core.History.History
|
||||
{
|
||||
Id = 1,
|
||||
Date = DateTime.UtcNow.AddHours(-5),
|
||||
Episode = episode,
|
||||
Series = series,
|
||||
Indexer = "nzbs.org",
|
||||
Quality = new QualityModel(Quality.HDTV720p)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
result.TotalRecords = result.Records.Count;
|
||||
|
||||
return Mapper.Map<PagingSpec<Core.History.History>, PagingResource<HistoryResource>>(result).AsResponse();
|
||||
}
|
||||
}
|
||||
}
|
21
NzbDrone.Api/History/HistoryResource.cs
Normal file
21
NzbDrone.Api/History/HistoryResource.cs
Normal file
@ -0,0 +1,21 @@
|
||||
using System;
|
||||
using NzbDrone.Api.REST;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Api.History
|
||||
{
|
||||
public class HistoryResource : RestResource
|
||||
{
|
||||
public int EpisodeId { get; set; }
|
||||
public int SeriesId { get; set; }
|
||||
public string NzbTitle { get; set; }
|
||||
public QualityModel Quality { get; set; }
|
||||
public DateTime Date { get; set; }
|
||||
public string Indexer { get; set; }
|
||||
public string NzbInfoUrl { get; set; }
|
||||
public string ReleaseGroup { get; set; }
|
||||
|
||||
public Episode Episode { get; set; }
|
||||
public Core.Tv.Series Series { get; set; }
|
||||
}
|
||||
}
|
@ -96,6 +96,8 @@
|
||||
<Compile Include="Frontend\IndexModule.cs" />
|
||||
<Compile Include="Frontend\StaticResourceProvider.cs" />
|
||||
<Compile Include="Frontend\StaticResourceMapper.cs" />
|
||||
<Compile Include="History\HistoryResource.cs" />
|
||||
<Compile Include="History\HistoryModule.cs" />
|
||||
<Compile Include="Indexers\IndexerModule.cs" />
|
||||
<Compile Include="Indexers\IndexerResource.cs" />
|
||||
<Compile Include="Indexers\ReleaseModule.cs" />
|
||||
|
@ -38,9 +38,10 @@ namespace NzbDrone.Core.Datastore
|
||||
|
||||
Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings");
|
||||
|
||||
Mapper.Entity<History.History>().RegisterModel("History")
|
||||
.Relationship()
|
||||
.HasOne(h => h.Episode, h => h.EpisodeId);
|
||||
Mapper.Entity<History.History>().RegisterModel("History");
|
||||
// .Relationship()
|
||||
// .HasOne(h => h.Episode, h => h.EpisodeId)
|
||||
// .HasOne(h => h.Series, h => h.SeriesId);
|
||||
|
||||
Mapper.Entity<Series>().RegisterModel("Series")
|
||||
.Ignore(s => s.Path)
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Marr.Data;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Tv;
|
||||
@ -16,6 +17,7 @@ namespace NzbDrone.Core.History
|
||||
public string NzbInfoUrl { get; set; }
|
||||
public string ReleaseGroup { get; set; }
|
||||
|
||||
public LazyLoaded<Episode> Episode { get; set; }
|
||||
public Episode Episode { get; set; }
|
||||
public Series Series { get; set; }
|
||||
}
|
||||
}
|
@ -9,6 +9,7 @@ namespace NzbDrone.Core.Tv
|
||||
{
|
||||
bool SeriesPathExists(string path);
|
||||
List<Series> Search(string title);
|
||||
|
||||
Series FindByTitle(string cleanTitle);
|
||||
Series FindByTvdbId(int tvdbId);
|
||||
void SetSeriesType(int seriesId, SeriesTypes seriesTypes);
|
||||
|
@ -4,7 +4,8 @@ define(['app', 'Shared/ModalRegion', 'AddSeries/AddSeriesLayout',
|
||||
'Calendar/CalendarCollectionView', 'Shared/NotificationView',
|
||||
'Shared/NotFoundView', 'MainMenuView',
|
||||
'Series/Details/SeriesDetailsView', 'Series/EpisodeCollection',
|
||||
'Settings/SettingsLayout', 'Missing/MissingLayout'],
|
||||
'Settings/SettingsLayout', 'Missing/MissingLayout',
|
||||
'History/HistoryLayout'],
|
||||
function (app, modalRegion) {
|
||||
|
||||
var controller = Backbone.Marionette.Controller.extend({
|
||||
@ -61,6 +62,12 @@ define(['app', 'Shared/ModalRegion', 'AddSeries/AddSeriesLayout',
|
||||
NzbDrone.mainRegion.show(new NzbDrone.Missing.MissingLayout());
|
||||
},
|
||||
|
||||
history: function () {
|
||||
this._setTitle('History');
|
||||
|
||||
NzbDrone.mainRegion.show(new NzbDrone.History.HistoryLayout());
|
||||
},
|
||||
|
||||
notFound: function () {
|
||||
this._setTitle('Not Found');
|
||||
NzbDrone.mainRegion.show(new NzbDrone.Shared.NotFoundView(this));
|
||||
|
37
UI/History/Collection.js
Normal file
37
UI/History/Collection.js
Normal file
@ -0,0 +1,37 @@
|
||||
"use strict";
|
||||
define(['app', 'History/Model'], function () {
|
||||
NzbDrone.Missing.Collection = Backbone.PageableCollection.extend({
|
||||
url : NzbDrone.Constants.ApiRoot + '/history',
|
||||
model : NzbDrone.History.Model,
|
||||
|
||||
state: {
|
||||
pageSize: 10,
|
||||
sortKey: "date",
|
||||
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;
|
||||
}
|
||||
});
|
||||
});
|
1
UI/History/ControlsColumnTemplate.html
Normal file
1
UI/History/ControlsColumnTemplate.html
Normal file
@ -0,0 +1 @@
|
||||
<i class="icon-search x-search" title="Search"></i>
|
2
UI/History/EpisodeColumnTemplate.html
Normal file
2
UI/History/EpisodeColumnTemplate.html
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
{{seasonNumber}}x{{paddedEpisodeNumber}}
|
89
UI/History/HistoryLayout.js
Normal file
89
UI/History/HistoryLayout.js
Normal file
@ -0,0 +1,89 @@
|
||||
"use strict";
|
||||
define([
|
||||
'app',
|
||||
'History/Collection',
|
||||
'Series/Index/Table/AirDateCell',
|
||||
'Shared/Toolbar/ToolbarView',
|
||||
'Shared/Toolbar/ToolbarLayout'
|
||||
],
|
||||
function () {
|
||||
NzbDrone.History.HistoryLayout = Backbone.Marionette.Layout.extend({
|
||||
template: 'History/HistoryLayoutTemplate',
|
||||
|
||||
regions: {
|
||||
history: '#x-history',
|
||||
toolbar: '#x-toolbar',
|
||||
pager : '#x-pager'
|
||||
},
|
||||
|
||||
showTable: function () {
|
||||
|
||||
var columns = [
|
||||
{
|
||||
name : 'seriesTitle',
|
||||
label : 'Series Title',
|
||||
editable : false,
|
||||
cell : Backgrid.TemplateBackedCell.extend({ template: 'History/SeriesTitleTemplate' }),
|
||||
headerCell: 'nzbDrone'
|
||||
},
|
||||
{
|
||||
name : 'episode',
|
||||
label : 'Episode',
|
||||
editable : false,
|
||||
sortable : false,
|
||||
cell : Backgrid.TemplateBackedCell.extend({ template: 'History/EpisodeColumnTemplate' }),
|
||||
headerCell: 'nzbDrone'
|
||||
},
|
||||
{
|
||||
name : 'title',
|
||||
label : 'Episode Title',
|
||||
editable : false,
|
||||
sortable : false,
|
||||
cell : 'string',
|
||||
headerCell: 'nzbDrone'
|
||||
},
|
||||
{
|
||||
name : 'airDate',
|
||||
label : 'Air Date',
|
||||
editable : false,
|
||||
cell : 'airDate',
|
||||
headerCell: 'nzbDrone'
|
||||
},
|
||||
{
|
||||
name : 'edit',
|
||||
label : '',
|
||||
editable : false,
|
||||
sortable : false,
|
||||
cell : Backgrid.TemplateBackedCell.extend({ template: 'History/ControlsColumnTemplate' }),
|
||||
headerCell: 'nzbDrone'
|
||||
}
|
||||
];
|
||||
|
||||
this.history.show(new Backgrid.Grid(
|
||||
{
|
||||
row : NzbDrone.History.Row,
|
||||
columns : columns,
|
||||
collection: this.historyCollection,
|
||||
className : 'table table-hover'
|
||||
}));
|
||||
|
||||
this.pager.show(new Backgrid.NzbDronePaginator({
|
||||
columns: columns,
|
||||
collection: this.historyCollection
|
||||
}));
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
this.historyCollection = new NzbDrone.History.Collection();
|
||||
this.historyCollection.fetch();
|
||||
},
|
||||
|
||||
onShow: function () {
|
||||
this.showTable();
|
||||
//this.toolbar.show(new NzbDrone.Shared.Toolbar.ToolbarLayout({right: [ viewButtons], context: this}));
|
||||
}
|
||||
|
||||
})
|
||||
;
|
||||
})
|
||||
;
|
11
UI/History/HistoryLayoutTemplate.html
Normal file
11
UI/History/HistoryLayoutTemplate.html
Normal file
@ -0,0 +1,11 @@
|
||||
<div id="x-toolbar"></div>
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<div id="x-history"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="span12">
|
||||
<div id="x-pager"></div>
|
||||
</div>
|
||||
</div>
|
6
UI/History/Model.js
Normal file
6
UI/History/Model.js
Normal file
@ -0,0 +1,6 @@
|
||||
"use strict";
|
||||
define(['app'], function (app) {
|
||||
NzbDrone.History.Model = Backbone.Model.extend({
|
||||
|
||||
});
|
||||
});
|
9
UI/History/Row.js
Normal file
9
UI/History/Row.js
Normal file
@ -0,0 +1,9 @@
|
||||
NzbDrone.Missing.Row = Backgrid.Row.extend({
|
||||
events: {
|
||||
'click .x-search' : 'search'
|
||||
},
|
||||
|
||||
search: function () {
|
||||
window.alert('Episode Search');
|
||||
}
|
||||
});
|
1
UI/History/SeriesTitleTemplate.html
Normal file
1
UI/History/SeriesTitleTemplate.html
Normal file
@ -0,0 +1 @@
|
||||
<a href="series/details/{{series.titleSlug}}">{{series.title}}</a>
|
@ -71,12 +71,11 @@ define([
|
||||
columns: columns,
|
||||
collection: this.missingCollection
|
||||
}));
|
||||
|
||||
this.missingCollection.getFirstPage();
|
||||
},
|
||||
|
||||
initialize: function () {
|
||||
this.missingCollection = new NzbDrone.Missing.Collection();
|
||||
this.missingCollection.fetch();
|
||||
},
|
||||
|
||||
onShow: function () {
|
||||
|
@ -17,6 +17,7 @@ require(['app', 'Controller'], function (app, controller) {
|
||||
'settings' : 'settings',
|
||||
'settings/:action(/:query)' : 'settings',
|
||||
'missing' : 'missing',
|
||||
'history' : 'history',
|
||||
':whatever' : 'notFound'
|
||||
}
|
||||
});
|
||||
|
@ -10,6 +10,11 @@ define(['app', 'Series/SeriesModel'], function () {
|
||||
sortKey: "title",
|
||||
order: -1,
|
||||
pageSize: 1000000
|
||||
},
|
||||
|
||||
queryParams: {
|
||||
sortKey: null,
|
||||
order: null
|
||||
}
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user