mirror of https://github.com/lidarr/Lidarr
Series Details started
This commit is contained in:
parent
e1a3637107
commit
bb27995eaf
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using AutoMapper;
|
||||
using NzbDrone.Api.Calendar;
|
||||
using NzbDrone.Api.Episodes;
|
||||
using NzbDrone.Api.QualityProfiles;
|
||||
using NzbDrone.Api.QualityType;
|
||||
using NzbDrone.Api.Resolvers;
|
||||
|
@ -48,6 +49,9 @@ namespace NzbDrone.Api
|
|||
.ForMember(dest => dest.EpisodeTitle, opt => opt.MapFrom(src => src.Title))
|
||||
.ForMember(dest => dest.Start, opt => opt.MapFrom(src => src.AirDate))
|
||||
.ForMember(dest => dest.End, opt => opt.ResolveUsing<EndTimeResolver>());
|
||||
|
||||
//Episode
|
||||
Mapper.CreateMap<Episode, EpisodeResource>();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using AutoMapper;
|
||||
using Nancy;
|
||||
using NzbDrone.Api.Extensions;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Api.Episodes
|
||||
{
|
||||
public class EpisodeModule : NzbDroneApiModule
|
||||
{
|
||||
private readonly EpisodeService _episodeService;
|
||||
|
||||
public EpisodeModule(EpisodeService episodeService)
|
||||
: base("/episodes")
|
||||
{
|
||||
_episodeService = episodeService;
|
||||
Get["/{seriesId}"] = x => GetEpisodesForSeries(x.SeriesId);
|
||||
}
|
||||
|
||||
private Response GetEpisodesForSeries(int seriesId)
|
||||
{
|
||||
var episodes = _episodeService.GetEpisodeBySeries(seriesId);
|
||||
return Mapper.Map<List<Episode>, List<EpisodeResource>>(episodes).AsResponse();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NzbDrone.Core.Tv;
|
||||
|
||||
namespace NzbDrone.Api.Episodes
|
||||
{
|
||||
public class EpisodeResource
|
||||
{
|
||||
public Int32 SeriesId { get; set; }
|
||||
public Int32 EpisodeId { get; set; }
|
||||
public Int32 EpisodeFileId { get; set; }
|
||||
public Int32 SeasonNumber { get; set; }
|
||||
public Int32 EpisodeNumber { get; set; }
|
||||
public String Title { get; set; }
|
||||
public DateTime AirDate { get; set; }
|
||||
public Int32 Status { get; set; }
|
||||
public String Overview { get; set; }
|
||||
public EpisodeFile EpisodeFile { get; set; }
|
||||
}
|
||||
}
|
|
@ -113,6 +113,8 @@
|
|||
<Compile Include="Calendar\CalendarModule.cs" />
|
||||
<Compile Include="Calendar\CalendarResource.cs" />
|
||||
<Compile Include="Directories\DirectoryModule.cs" />
|
||||
<Compile Include="Episodes\EpisodeModule.cs" />
|
||||
<Compile Include="Episodes\EpisodeResource.cs" />
|
||||
<Compile Include="Extensions\NancyJsonSerializer.cs" />
|
||||
<Compile Include="Extensions\Serializer.cs" />
|
||||
<Compile Include="FrontendModule\IndexModule.cs" />
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
define(['app', 'Shared/ModalRegion', 'AddSeries/AddSeriesLayout', 'Series/SeriesCollectionView',
|
||||
'Upcoming/UpcomingCollectionView', 'Calendar/CalendarCollectionView', 'Shared/NotificationView',
|
||||
'Shared/NotFoundView', 'MainMenuView', 'HeaderView'], function (app, modalRegion) {
|
||||
define(['app', 'Shared/ModalRegion', 'AddSeries/AddSeriesLayout',
|
||||
'Series/SeriesCollectionView', 'Upcoming/UpcomingCollectionView',
|
||||
'Calendar/CalendarCollectionView', 'Shared/NotificationView',
|
||||
'Shared/NotFoundView', 'MainMenuView', 'HeaderView',
|
||||
'Series/Details/SeriesDetailsView', 'Series/Details/EpisodeCollection'],
|
||||
function (app, modalRegion) {
|
||||
|
||||
var controller = Backbone.Marionette.Controller.extend({
|
||||
|
||||
|
@ -26,6 +29,36 @@
|
|||
NzbDrone.mainRegion.show(new NzbDrone.Calendar.CalendarCollectionView(this, action, query, calendarCollection));
|
||||
},
|
||||
|
||||
seriesDetails: function (query) {
|
||||
this.setTitle('Series Title Goes Here');
|
||||
// var seriesModel = new NzbDrone.Series.SeriesModel();
|
||||
// seriesModel.fetch();
|
||||
|
||||
var seriesEpisodes = new NzbDrone.Series.Details.EpisodeCollection({ seriesId: query });
|
||||
seriesEpisodes.fetch({
|
||||
success: function (collection) {
|
||||
var seasons = collection.models.groupBy(function(episode){
|
||||
var seasonNumber = episode.get('seasonNumber');
|
||||
|
||||
if (seasonNumber === undefined)
|
||||
return 0;
|
||||
|
||||
return seasonNumber;
|
||||
});
|
||||
|
||||
var seasonCollection = new NzbDrone.Series.Details.SeasonCollection();
|
||||
|
||||
$.each(seasons, function(index, season){
|
||||
seasonCollection.add(new NzbDrone.Series.Details.SeasonModel(
|
||||
{ seasonNumber: index, episodes: season })
|
||||
);
|
||||
});
|
||||
|
||||
NzbDrone.mainRegion.show(new NzbDrone.Series.Details.SeriesDetailsView({ collection: seasonCollection }));
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
notFound: function () {
|
||||
this.setTitle('Not Found');
|
||||
NzbDrone.mainRegion.show(new NzbDrone.Shared.NotFoundView(this));
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
<CodeAnalysisIgnoreGeneratedCode>true</CodeAnalysisIgnoreGeneratedCode>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Content Include="HeaderView.js" />
|
||||
<Content Include="MainMenuView.js" />
|
||||
<Content Include="AddSeries\addSeries.css" />
|
||||
<Content Include="AddSeries\AddSeriesLayout.js" />
|
||||
|
@ -121,6 +122,12 @@
|
|||
<Content Include="Routing.js" />
|
||||
<Content Include="Series\Delete\DeleteSeriesTemplate.html" />
|
||||
<Content Include="Series\Delete\DeleteSeriesView.js" />
|
||||
<Content Include="Series\Details\EpisodeModel.js" />
|
||||
<Content Include="Series\Details\SeasonCollection.js" />
|
||||
<Content Include="Series\Details\SeasonCollectionTemplate.html" />
|
||||
<Content Include="Series\Details\SeasonCollectionView.js" />
|
||||
<Content Include="Series\Details\SeriesDetailsTemplate.html" />
|
||||
<Content Include="Series\Details\SeriesDetailsView.js" />
|
||||
<Content Include="Series\Edit\EditSeriesTemplate.html" />
|
||||
<Content Include="Series\Edit\EditSeriesView.js" />
|
||||
<Content Include="Series\EmptySeriesCollectionTemplate.html" />
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
'series/index': 'series',
|
||||
'series/add': 'addSeries',
|
||||
'series/add/:action(/:query)': 'addSeries',
|
||||
'series/details/:query': 'seriesDetails',
|
||||
'upcoming': 'upcoming',
|
||||
'upcoming/index': 'upcoming',
|
||||
'calendar': 'calendar',
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
define(['app', 'Series/Details/EpisodeModel'], function () {
|
||||
NzbDrone.Series.Details.EpisodeCollection = Backbone.Collection.extend({
|
||||
initialize: function(options) {
|
||||
this.seriesId = options.seriesId;
|
||||
},
|
||||
|
||||
url: function(){
|
||||
return NzbDrone.Constants.ApiRoot + '/episodes/' + this.seriesId;
|
||||
},
|
||||
|
||||
model: NzbDrone.Series.Details.EpisodeModel
|
||||
});
|
||||
});
|
|
@ -0,0 +1 @@
|
|||
{{title}}
|
|
@ -0,0 +1,24 @@
|
|||
'use strict';
|
||||
|
||||
define([
|
||||
'app',
|
||||
'Series/Details/SeasonModel'
|
||||
|
||||
], function () {
|
||||
|
||||
NzbDrone.Series.Details.EpisodeItemView = Backbone.Marionette.ItemView.extend({
|
||||
template: 'Series/Details/EpisodeItemTemplate',
|
||||
tagName: 'tr',
|
||||
|
||||
ui: {
|
||||
|
||||
},
|
||||
|
||||
events: {
|
||||
|
||||
},
|
||||
onRender: function () {
|
||||
NzbDrone.ModelBinder.bind(this.model, this.el);
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,12 @@
|
|||
define(['app'], function (app) {
|
||||
NzbDrone.Series.Details.EpisodeModel = Backbone.Model.extend({
|
||||
|
||||
mutators: {
|
||||
|
||||
},
|
||||
|
||||
defaults: {
|
||||
seasonNumber: 0
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,10 @@
|
|||
define(['app'], function (app) {
|
||||
NzbDrone.Series.Details.SeasonCollection = Backbone.Collection.extend({
|
||||
// Todo: Why does this throw: "this.model is undefined" - Chnaging to another model fixes it
|
||||
//model: NzbDrone.Series.Details.SeasonModel,
|
||||
model: NzbDrone.Series.Details.EpisodeModel,
|
||||
comparator: function(model) {
|
||||
return -model.get('seasonNumber');
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,13 @@
|
|||
<h3>Season {{seasonNumber}}</h3>
|
||||
<table class="table table-hover x-season-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Title</th>
|
||||
<th>Air Date</th>
|
||||
<th>Quality</th>
|
||||
<th>Controls</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
|
@ -0,0 +1,15 @@
|
|||
'use strict';
|
||||
|
||||
define(['app', 'Series/Details/EpisodeItemView'], function (app) {
|
||||
NzbDrone.Series.Details.SeasonCollectionView = Backbone.Marionette.CompositeView.extend({
|
||||
itemView: NzbDrone.Series.Details.EpisodeItemView,
|
||||
itemViewContainer: '#seasons',
|
||||
template: 'Series/Details/SeasonCollectionTemplate',
|
||||
|
||||
initialize: function() {
|
||||
var episodes = this.model.get('episodes');
|
||||
var test = 1;
|
||||
//this.collection
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
define(['app', 'Series/Details/SeasonCollection'], function (app) {
|
||||
NzbDrone.Series.Details.SeasonModel = Backbone.Model.extend({
|
||||
//Season Number
|
||||
//Episodes
|
||||
|
||||
initialize: function(options) {
|
||||
this.seasonNumber = options.seasonNumber;
|
||||
this.episodes = options.episodes;
|
||||
}
|
||||
});
|
||||
});
|
|
@ -0,0 +1,4 @@
|
|||
<div>
|
||||
<div id="details"></div>
|
||||
<div id="seasons"></div>
|
||||
</div>
|
|
@ -0,0 +1,19 @@
|
|||
define(['app', 'Quality/QualityProfileCollection', 'Series/Details/SeasonCollectionView'], function (app, qualityProfileCollection) {
|
||||
NzbDrone.Series.Details.SeriesDetailsView = Backbone.Marionette.CompositeView.extend({
|
||||
itemView: NzbDrone.Series.Details.SeasonCollectionView,
|
||||
itemViewContainer: '#seasons',
|
||||
template: 'Series/Details/SeriesDetailsTemplate',
|
||||
qualityProfileCollection: qualityProfileCollection,
|
||||
|
||||
initialize: function (options) {
|
||||
this.collection = options.collection;
|
||||
|
||||
this.qualityProfileCollection.fetch();
|
||||
},
|
||||
|
||||
onCompositeCollectionRendered: function()
|
||||
{
|
||||
var test = 1;
|
||||
}
|
||||
});
|
||||
});
|
|
@ -32,6 +32,7 @@ define('app', function () {
|
|||
window.NzbDrone.Series = {};
|
||||
window.NzbDrone.Series.Edit = {};
|
||||
window.NzbDrone.Series.Delete = {};
|
||||
window.NzbDrone.Series.Details = {};
|
||||
window.NzbDrone.AddSeries = {};
|
||||
window.NzbDrone.AddSeries.New = {};
|
||||
window.NzbDrone.AddSeries.Existing = {};
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace NzbDrone.Core.Tv
|
|||
Episode GetEpisode(int id);
|
||||
Episode GetEpisode(int seriesId, int seasonNumber, int episodeNumber);
|
||||
Episode GetEpisode(int seriesId, DateTime date);
|
||||
IList<Episode> GetEpisodeBySeries(int seriesId);
|
||||
List<Episode> GetEpisodeBySeries(int seriesId);
|
||||
IList<Episode> GetEpisodesBySeason(int seriesId, int seasonNumber);
|
||||
IList<Episode> GetEpisodesByParseResult(EpisodeParseResult parseResult);
|
||||
IList<Episode> EpisodesWithoutFiles(bool includeSpecials);
|
||||
|
@ -56,32 +56,32 @@ namespace NzbDrone.Core.Tv
|
|||
_episodeRepository.Insert(episode);
|
||||
}
|
||||
|
||||
public virtual Episode GetEpisode(int id)
|
||||
public Episode GetEpisode(int id)
|
||||
{
|
||||
return _episodeRepository.Get(id);
|
||||
}
|
||||
|
||||
public virtual Episode GetEpisode(int seriesId, int seasonNumber, int episodeNumber)
|
||||
public Episode GetEpisode(int seriesId, int seasonNumber, int episodeNumber)
|
||||
{
|
||||
return _episodeRepository.Get(seriesId, seasonNumber, episodeNumber);
|
||||
}
|
||||
|
||||
public virtual Episode GetEpisode(int seriesId, DateTime date)
|
||||
public Episode GetEpisode(int seriesId, DateTime date)
|
||||
{
|
||||
return _episodeRepository.Get(seriesId, date);
|
||||
}
|
||||
|
||||
public virtual IList<Episode> GetEpisodeBySeries(int seriesId)
|
||||
public List<Episode> GetEpisodeBySeries(int seriesId)
|
||||
{
|
||||
return _episodeRepository.GetEpisodes(seriesId);
|
||||
return _episodeRepository.GetEpisodes(seriesId).ToList();
|
||||
}
|
||||
|
||||
public virtual IList<Episode> GetEpisodesBySeason(int seriesId, int seasonNumber)
|
||||
public IList<Episode> GetEpisodesBySeason(int seriesId, int seasonNumber)
|
||||
{
|
||||
return _episodeRepository.GetEpisodes(seriesId, seasonNumber);
|
||||
}
|
||||
|
||||
public virtual IList<Episode> GetEpisodesByParseResult(EpisodeParseResult parseResult)
|
||||
public IList<Episode> GetEpisodesByParseResult(EpisodeParseResult parseResult)
|
||||
{
|
||||
var result = new List<Episode>();
|
||||
|
||||
|
@ -159,22 +159,22 @@ namespace NzbDrone.Core.Tv
|
|||
return result;
|
||||
}
|
||||
|
||||
public virtual IList<Episode> EpisodesWithoutFiles(bool includeSpecials)
|
||||
public IList<Episode> EpisodesWithoutFiles(bool includeSpecials)
|
||||
{
|
||||
return _episodeRepository.EpisodesWithoutFiles(includeSpecials);
|
||||
}
|
||||
|
||||
public virtual IList<Episode> GetEpisodesByFileId(int episodeFileId)
|
||||
public IList<Episode> GetEpisodesByFileId(int episodeFileId)
|
||||
{
|
||||
return _episodeRepository.GetEpisodeByFileId(episodeFileId);
|
||||
}
|
||||
|
||||
public virtual IList<Episode> EpisodesWithFiles()
|
||||
public IList<Episode> EpisodesWithFiles()
|
||||
{
|
||||
return _episodeRepository.EpisodesWithFiles();
|
||||
}
|
||||
|
||||
public virtual void RefreshEpisodeInfo(Series series)
|
||||
public void RefreshEpisodeInfo(Series series)
|
||||
{
|
||||
logger.Trace("Starting episode info refresh for series: {0}", series.Title.WithDefault(series.Id));
|
||||
var successCount = 0;
|
||||
|
@ -270,17 +270,17 @@ namespace NzbDrone.Core.Tv
|
|||
DeleteEpisodesNotInTvdb(series, tvdbEpisodes);
|
||||
}
|
||||
|
||||
public virtual void UpdateEpisode(Episode episode)
|
||||
public void UpdateEpisode(Episode episode)
|
||||
{
|
||||
_episodeRepository.Update(episode);
|
||||
}
|
||||
|
||||
public virtual IList<int> GetEpisodeNumbersBySeason(int seriesId, int seasonNumber)
|
||||
public IList<int> GetEpisodeNumbersBySeason(int seriesId, int seasonNumber)
|
||||
{
|
||||
return GetEpisodesBySeason(seriesId, seasonNumber).Select(c => c.Id).ToList();
|
||||
}
|
||||
|
||||
public virtual void SetEpisodeIgnore(int episodeId, bool isIgnored)
|
||||
public void SetEpisodeIgnore(int episodeId, bool isIgnored)
|
||||
{
|
||||
var episode = _episodeRepository.Get(episodeId);
|
||||
_episodeRepository.SetIgnoreFlat(episode, isIgnored);
|
||||
|
@ -288,7 +288,7 @@ namespace NzbDrone.Core.Tv
|
|||
logger.Info("Ignore flag for Episode:{0} was set to {1}", episodeId, isIgnored);
|
||||
}
|
||||
|
||||
public virtual bool IsFirstOrLastEpisodeOfSeason(int seriesId, int seasonNumber, int episodeNumber)
|
||||
public bool IsFirstOrLastEpisodeOfSeason(int seriesId, int seasonNumber, int episodeNumber)
|
||||
{
|
||||
var episodes = GetEpisodesBySeason(seriesId, seasonNumber).OrderBy(e => e.EpisodeNumber);
|
||||
|
||||
|
@ -316,7 +316,7 @@ namespace NzbDrone.Core.Tv
|
|||
logger.Trace("Deleted episodes that no longer exist in TVDB for {0}", series.Id);
|
||||
}
|
||||
|
||||
public virtual void SetPostDownloadStatus(List<int> episodeIds, PostDownloadStatusType postDownloadStatus)
|
||||
public void SetPostDownloadStatus(List<int> episodeIds, PostDownloadStatusType postDownloadStatus)
|
||||
{
|
||||
if (episodeIds.Count == 0) throw new ArgumentException("episodeIds should contain one or more episode ids.");
|
||||
|
||||
|
@ -332,12 +332,12 @@ namespace NzbDrone.Core.Tv
|
|||
logger.Trace("Updating PostDownloadStatus for {0} episode(s) to {1}", episodeIds.Count, postDownloadStatus);
|
||||
}
|
||||
|
||||
public virtual void UpdateEpisodes(List<Episode> episodes)
|
||||
public void UpdateEpisodes(List<Episode> episodes)
|
||||
{
|
||||
_episodeRepository.UpdateMany(episodes);
|
||||
}
|
||||
|
||||
public virtual Episode GetEpisodeBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber)
|
||||
public Episode GetEpisodeBySceneNumbering(int seriesId, int seasonNumber, int episodeNumber)
|
||||
{
|
||||
return _episodeRepository.GetEpisodeBySceneNumbering(seriesId, seasonNumber, episodeNumber);
|
||||
}
|
||||
|
|
|
@ -53,7 +53,5 @@ namespace NzbDrone.Core.Tv
|
|||
public int EpisodeFileCount { get; set; }
|
||||
public int SeasonCount { get; set; }
|
||||
public DateTime? NextAiring { get; set; }
|
||||
|
||||
public List<Episode> Episodes { get; set; }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue