Adding history
This commit is contained in:
parent
6a3d886588
commit
7ab1084437
|
@ -2,6 +2,7 @@
|
||||||
using AutoMapper;
|
using AutoMapper;
|
||||||
using NzbDrone.Api.Calendar;
|
using NzbDrone.Api.Calendar;
|
||||||
using NzbDrone.Api.Episodes;
|
using NzbDrone.Api.Episodes;
|
||||||
|
using NzbDrone.Api.History;
|
||||||
using NzbDrone.Api.Missing;
|
using NzbDrone.Api.Missing;
|
||||||
using NzbDrone.Api.QualityProfiles;
|
using NzbDrone.Api.QualityProfiles;
|
||||||
using NzbDrone.Api.QualityType;
|
using NzbDrone.Api.QualityType;
|
||||||
|
@ -42,6 +43,10 @@ namespace NzbDrone.Api
|
||||||
|
|
||||||
//Episode Paging
|
//Episode Paging
|
||||||
Mapper.CreateMap<PagingSpec<Episode>, PagingResource<EpisodeResource>>();
|
Mapper.CreateMap<PagingSpec<Episode>, PagingResource<EpisodeResource>>();
|
||||||
|
|
||||||
|
//History
|
||||||
|
Mapper.CreateMap<Core.History.History, HistoryResource>();
|
||||||
|
Mapper.CreateMap<PagingSpec<Core.History.History>, PagingResource<HistoryResource>>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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\IndexModule.cs" />
|
||||||
<Compile Include="Frontend\StaticResourceProvider.cs" />
|
<Compile Include="Frontend\StaticResourceProvider.cs" />
|
||||||
<Compile Include="Frontend\StaticResourceMapper.cs" />
|
<Compile Include="Frontend\StaticResourceMapper.cs" />
|
||||||
|
<Compile Include="History\HistoryResource.cs" />
|
||||||
|
<Compile Include="History\HistoryModule.cs" />
|
||||||
<Compile Include="Indexers\IndexerModule.cs" />
|
<Compile Include="Indexers\IndexerModule.cs" />
|
||||||
<Compile Include="Indexers\IndexerResource.cs" />
|
<Compile Include="Indexers\IndexerResource.cs" />
|
||||||
<Compile Include="Indexers\ReleaseModule.cs" />
|
<Compile Include="Indexers\ReleaseModule.cs" />
|
||||||
|
|
|
@ -38,9 +38,10 @@ namespace NzbDrone.Core.Datastore
|
||||||
|
|
||||||
Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings");
|
Mapper.Entity<SceneMapping>().RegisterModel("SceneMappings");
|
||||||
|
|
||||||
Mapper.Entity<History.History>().RegisterModel("History")
|
Mapper.Entity<History.History>().RegisterModel("History");
|
||||||
.Relationship()
|
// .Relationship()
|
||||||
.HasOne(h => h.Episode, h => h.EpisodeId);
|
// .HasOne(h => h.Episode, h => h.EpisodeId)
|
||||||
|
// .HasOne(h => h.Series, h => h.SeriesId);
|
||||||
|
|
||||||
Mapper.Entity<Series>().RegisterModel("Series")
|
Mapper.Entity<Series>().RegisterModel("Series")
|
||||||
.Ignore(s => s.Path)
|
.Ignore(s => s.Path)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using Marr.Data;
|
using Marr.Data;
|
||||||
using NzbDrone.Core.Datastore;
|
using NzbDrone.Core.Datastore;
|
||||||
using NzbDrone.Core.Tv;
|
using NzbDrone.Core.Tv;
|
||||||
|
@ -16,6 +17,7 @@ namespace NzbDrone.Core.History
|
||||||
public string NzbInfoUrl { get; set; }
|
public string NzbInfoUrl { get; set; }
|
||||||
public string ReleaseGroup { 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);
|
bool SeriesPathExists(string path);
|
||||||
List<Series> Search(string title);
|
List<Series> Search(string title);
|
||||||
|
|
||||||
Series FindByTitle(string cleanTitle);
|
Series FindByTitle(string cleanTitle);
|
||||||
Series FindByTvdbId(int tvdbId);
|
Series FindByTvdbId(int tvdbId);
|
||||||
void SetSeriesType(int seriesId, SeriesTypes seriesTypes);
|
void SetSeriesType(int seriesId, SeriesTypes seriesTypes);
|
||||||
|
|
|
@ -4,7 +4,8 @@ define(['app', 'Shared/ModalRegion', 'AddSeries/AddSeriesLayout',
|
||||||
'Calendar/CalendarCollectionView', 'Shared/NotificationView',
|
'Calendar/CalendarCollectionView', 'Shared/NotificationView',
|
||||||
'Shared/NotFoundView', 'MainMenuView',
|
'Shared/NotFoundView', 'MainMenuView',
|
||||||
'Series/Details/SeriesDetailsView', 'Series/EpisodeCollection',
|
'Series/Details/SeriesDetailsView', 'Series/EpisodeCollection',
|
||||||
'Settings/SettingsLayout', 'Missing/MissingLayout'],
|
'Settings/SettingsLayout', 'Missing/MissingLayout',
|
||||||
|
'History/HistoryLayout'],
|
||||||
function (app, modalRegion) {
|
function (app, modalRegion) {
|
||||||
|
|
||||||
var controller = Backbone.Marionette.Controller.extend({
|
var controller = Backbone.Marionette.Controller.extend({
|
||||||
|
@ -61,6 +62,12 @@ define(['app', 'Shared/ModalRegion', 'AddSeries/AddSeriesLayout',
|
||||||
NzbDrone.mainRegion.show(new NzbDrone.Missing.MissingLayout());
|
NzbDrone.mainRegion.show(new NzbDrone.Missing.MissingLayout());
|
||||||
},
|
},
|
||||||
|
|
||||||
|
history: function () {
|
||||||
|
this._setTitle('History');
|
||||||
|
|
||||||
|
NzbDrone.mainRegion.show(new NzbDrone.History.HistoryLayout());
|
||||||
|
},
|
||||||
|
|
||||||
notFound: function () {
|
notFound: function () {
|
||||||
this._setTitle('Not Found');
|
this._setTitle('Not Found');
|
||||||
NzbDrone.mainRegion.show(new NzbDrone.Shared.NotFoundView(this));
|
NzbDrone.mainRegion.show(new NzbDrone.Shared.NotFoundView(this));
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1 @@
|
||||||
|
<i class="icon-search x-search" title="Search"></i>
|
|
@ -0,0 +1,2 @@
|
||||||
|
|
||||||
|
{{seasonNumber}}x{{paddedEpisodeNumber}}
|
|
@ -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}));
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
;
|
||||||
|
})
|
||||||
|
;
|
|
@ -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>
|
|
@ -0,0 +1,6 @@
|
||||||
|
"use strict";
|
||||||
|
define(['app'], function (app) {
|
||||||
|
NzbDrone.History.Model = Backbone.Model.extend({
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,9 @@
|
||||||
|
NzbDrone.Missing.Row = Backgrid.Row.extend({
|
||||||
|
events: {
|
||||||
|
'click .x-search' : 'search'
|
||||||
|
},
|
||||||
|
|
||||||
|
search: function () {
|
||||||
|
window.alert('Episode Search');
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1 @@
|
||||||
|
<a href="series/details/{{series.titleSlug}}">{{series.title}}</a>
|
|
@ -71,12 +71,11 @@ define([
|
||||||
columns: columns,
|
columns: columns,
|
||||||
collection: this.missingCollection
|
collection: this.missingCollection
|
||||||
}));
|
}));
|
||||||
|
|
||||||
this.missingCollection.getFirstPage();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
initialize: function () {
|
initialize: function () {
|
||||||
this.missingCollection = new NzbDrone.Missing.Collection();
|
this.missingCollection = new NzbDrone.Missing.Collection();
|
||||||
|
this.missingCollection.fetch();
|
||||||
},
|
},
|
||||||
|
|
||||||
onShow: function () {
|
onShow: function () {
|
||||||
|
|
|
@ -17,6 +17,7 @@ require(['app', 'Controller'], function (app, controller) {
|
||||||
'settings' : 'settings',
|
'settings' : 'settings',
|
||||||
'settings/:action(/:query)' : 'settings',
|
'settings/:action(/:query)' : 'settings',
|
||||||
'missing' : 'missing',
|
'missing' : 'missing',
|
||||||
|
'history' : 'history',
|
||||||
':whatever' : 'notFound'
|
':whatever' : 'notFound'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,6 +10,11 @@ define(['app', 'Series/SeriesModel'], function () {
|
||||||
sortKey: "title",
|
sortKey: "title",
|
||||||
order: -1,
|
order: -1,
|
||||||
pageSize: 1000000
|
pageSize: 1000000
|
||||||
|
},
|
||||||
|
|
||||||
|
queryParams: {
|
||||||
|
sortKey: null,
|
||||||
|
order: null
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -58,6 +58,7 @@ define('app', function () {
|
||||||
window.NzbDrone.Settings.System = {};
|
window.NzbDrone.Settings.System = {};
|
||||||
window.NzbDrone.Settings.Misc = {};
|
window.NzbDrone.Settings.Misc = {};
|
||||||
window.NzbDrone.Missing = {};
|
window.NzbDrone.Missing = {};
|
||||||
|
window.NzbDrone.History = {};
|
||||||
|
|
||||||
window.NzbDrone.Events = {
|
window.NzbDrone.Events = {
|
||||||
//TODO: Move to commands
|
//TODO: Move to commands
|
||||||
|
|
Loading…
Reference in New Issue