Calendar colouring, upcoming list shows yesterday

Cleaned up series file a bit.
Added spoon for common sugar tasks.
This commit is contained in:
Mark McDowall 2013-02-28 20:59:06 -08:00
parent 14cf5bf3cc
commit da2c0d1d65
15 changed files with 130 additions and 68 deletions

View File

@ -39,7 +39,8 @@ namespace NzbDrone.Api
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id)) .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
.ForMember(dest => dest.CustomStartDate, opt => opt.ResolveUsing<NullableDatetimeToString>().FromMember(src => src.CustomStartDate)) .ForMember(dest => dest.CustomStartDate, opt => opt.ResolveUsing<NullableDatetimeToString>().FromMember(src => src.CustomStartDate))
.ForMember(dest => dest.BacklogSetting, opt => opt.MapFrom(src => (Int32)src.BacklogSetting)) .ForMember(dest => dest.BacklogSetting, opt => opt.MapFrom(src => (Int32)src.BacklogSetting))
.ForMember(dest => dest.NextAiring, opt => opt.ResolveUsing<NextAiringResolver>()); .ForMember(dest => dest.NextAiring, opt => opt.ResolveUsing<NextAiringResolver>())
.ForMember(dest => dest.QualityProfileName, opt => opt.MapFrom(src => src.QualityProfile.Name));
//Calendar //Calendar
Mapper.CreateMap<Episode, CalendarResource>() Mapper.CreateMap<Episode, CalendarResource>()

View File

@ -22,7 +22,7 @@ namespace NzbDrone.Api.Calendar
private Response GetEpisodesBetweenStartAndEndDate() private Response GetEpisodesBetweenStartAndEndDate()
{ {
var start = DateTime.Today; var start = DateTime.Today.AddDays(-1);
var end = DateTime.Today.AddDays(7); var end = DateTime.Today.AddDays(7);
var queryStart = Request.Query.Start; var queryStart = Request.Query.Start;

View File

@ -4,6 +4,7 @@ using System.Linq;
using System.Text; using System.Text;
using NzbDrone.Api.QualityProfiles; using NzbDrone.Api.QualityProfiles;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Qualities;
namespace NzbDrone.Api.Series namespace NzbDrone.Api.Series
{ {

View File

@ -20,6 +20,7 @@ define(['app', 'Calendar/CalendarItemView'], function (app) {
allDayDefault: false, allDayDefault: false,
ignoreTimezone: false, ignoreTimezone: false,
weekMode: 'variable', weekMode: 'variable',
timeFormat: 'h(:mm)tt',
header: { header: {
left: 'prev,next today', left: 'prev,next today',
center: 'title', center: 'title',
@ -31,6 +32,9 @@ define(['app', 'Calendar/CalendarItemView'], function (app) {
}, },
events: this.getEvents, events: this.getEvents,
eventRender: function (event, element) { eventRender: function (event, element) {
$(element).addClass(event.statusLevel);
$(element).children('.fc-event-inner').addClass(event.statusLevel);
element.popover({ element.popover({
title: '{seriesTitle} - {season}x{episode} - {episodeTitle}'.assign({ title: '{seriesTitle} - {season}x{episode} - {episodeTitle}'.assign({
seriesTitle: event.seriesTitle, seriesTitle: event.seriesTitle,

View File

@ -3,4 +3,4 @@
<h4>{{month}}</h4> <h4>{{month}}</h4>
</div> </div>
<h4>{{seriesTitle}}</h4> <h4>{{seriesTitle}}</h4>
<p>{{startTime}}<span class="pull-right">{{seasonNumber}}x{{paddedEpisodeNumber}}</span><br>{{episodeTitle}}</p> <p>{{startTime}} {{bestDateString}}<span class="pull-right">{{seasonNumber}}x{{paddedEpisodeNumber}}</span><br>{{episodeTitle}}</p>

View File

@ -33,11 +33,16 @@
if (currentTime.isBetween(start, end)) if (currentTime.isBetween(start, end))
return 'warning'; return 'warning';
if (status === 'Missing') return 'danger'; if (start.isBefore(currentTime) || status === 'Missing')
return 'danger';
if (status === 'Ready') return 'success'; if (status === 'Ready') return 'success';
return 'info'; return 'primary';
} },
bestDateString: function () {
return bestDateString(this.get('start'));
},
}, },
defaults: { defaults: {
status: 0 status: 0

View File

@ -831,6 +831,45 @@ ul.stat-list {
text-align: center; text-align: center;
} }
#calendar .success {
border-color: #4cb158;
background-color: #4cb158;
}
#calendar .danger {
border-color: #ea494a;
background-color: #ea494a;
}
#calendar .info {
border-color: #14b8d4;
background-color: #14b8d4;
}
#calendar .primary {
border-color: #007ccd;
background-color: #007ccd;
}
#calendar .warning {
border-color: #ffa93c;
background-color: #ffa93c;
}
#calendar .purple {
border-color: #7932ea;
background-color: #7932ea;
}
#calendar .inverse {
border-color: #333;
background-color: #333;
}
#calendar .fc-state-highlight {
background: rgba(20, 184, 212, .2);
}
/* ============== tags ============== */ /* ============== tags ============== */
.tag { .tag {
display: inline-block; display: inline-block;

View File

@ -1,6 +1,6 @@
define(['app', 'Shared/ModalRegion', 'AddSeries/AddSeriesLayout', 'Series/SeriesCollectionView', define(['app', 'Shared/ModalRegion', 'AddSeries/AddSeriesLayout', 'Series/SeriesCollectionView',
'Upcoming/UpcomingCollectionView', 'Calendar/CalendarCollectionView', 'Shared/NotificationView', 'Upcoming/UpcomingCollectionView', 'Calendar/CalendarCollectionView', 'Shared/NotificationView',
'Shared/NotFoundView', 'MainMenuView'], function (app, modalRegion) { 'Shared/NotFoundView', 'MainMenuView', 'HeaderView'], function (app, modalRegion) {
var controller = Backbone.Marionette.Controller.extend({ var controller = Backbone.Marionette.Controller.extend({

View File

@ -0,0 +1,31 @@
define(['app'], function () {
NzbDrone.HeaderView = Backbone.Marionette.ItemView.extend({
events: {
'click #logo': 'onClick'
},
onClick: function (event) {
event.preventDefault();
var target = $(event.target);
var href = undefined;
//look down for <a/>
href = event.target.getAttribute('href');
if (href && href.startsWith('http')) {
window.location.href = href;
} else {
NzbDrone.Router.navigate(href, { trigger: true, replace: true });
}
},
initialize: function () {
this.setElement($('#in-nav'));
}
});
return new NzbDrone.HeaderView();
});

View File

@ -34,12 +34,14 @@
<div id="in-nav"> <div id="in-nav">
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class=span2>
<a id="logo" href="/"> <a id="logo" href="/">
<h4>Nzb<strong>Drone</strong></h4> <h4>Nzb<strong>Drone</strong></h4>
</a> </a>
</div> </div>
</div> </div>
</div> </div>
</div>
<div id="in-sub-nav"> <div id="in-sub-nav">
<div class="container"> <div class="container">
<div class="row"> <div class="row">
@ -109,6 +111,7 @@
<script src="/static/Mixins/backbone.marionette.templates.js"></script> <script src="/static/Mixins/backbone.marionette.templates.js"></script>
<script src="/static/Mixins/backbone.ajax.js"></script> <script src="/static/Mixins/backbone.ajax.js"></script>
<script src="/static/Mixins/tablesorter.extensions.js"></script> <script src="/static/Mixins/tablesorter.extensions.js"></script>
<script src="/static/Mixins/spoon.js"></script>
<script data-main="/static/app" src="/static/JsLibraries/require.js"></script> <script data-main="/static/app" src="/static/JsLibraries/require.js"></script>
<script src="/static/Routing.js"></script> <script src="/static/Routing.js"></script>

View File

@ -0,0 +1,12 @@
function bestDateString(sourceDate){
if (!sourceDate) return '';
var date = Date.create(sourceDate);
if (date.isYesterday()) return 'Yesterday';
if (date.isToday()) return 'Today';
if (date.isTomorrow()) return 'Tomorrow';
if (date.isBefore(Date.create().addDays(7))) return date.format('{Weekday}');
return date.format('{MM}/{dd}/{yyyy}');
}

View File

@ -3,18 +3,7 @@
mutators: { mutators: {
bestDateString: function () { bestDateString: function () {
var dateSource = this.get('nextAiring'); return bestDateString(this.get('nextAiring'));
if (!dateSource) return '';
var date = Date.create(dateSource);
if (date.isYesterday()) return 'Yesterday';
if (date.isToday()) return 'Today';
if (date.isTomorrow()) return 'Tomorrow';
if (date.isBefore(Date.create().addDays(7))) return date.format('{Weekday}');
return date.format('{MM}/{dd}/{yyyy}');
}, },
percentOfEpisodes: function () { percentOfEpisodes: function () {

View File

@ -182,7 +182,6 @@ namespace NzbDrone.Core.Tv
var tvdbEpisodes = _tvDbProvider.GetEpisodes(series.TvDbId); var tvdbEpisodes = _tvDbProvider.GetEpisodes(series.TvDbId);
var seriesEpisodes = GetEpisodeBySeries(series.Id); var seriesEpisodes = GetEpisodeBySeries(series.Id);
var updateList = new List<Episode>(); var updateList = new List<Episode>();
var newList = new List<Episode>(); var newList = new List<Episode>();
@ -237,10 +236,15 @@ namespace NzbDrone.Core.Tv
episodeToUpdate.SeasonNumber = episode.SeasonNumber; episodeToUpdate.SeasonNumber = episode.SeasonNumber;
episodeToUpdate.AbsoluteEpisodeNumber = episode.AbsoluteEpisodeNumber; episodeToUpdate.AbsoluteEpisodeNumber = episode.AbsoluteEpisodeNumber;
episodeToUpdate.Title = episode.Title; episodeToUpdate.Title = episode.Title;
episodeToUpdate.Overview = episode.Overview; episodeToUpdate.Overview = episode.Overview;
episodeToUpdate.AirDate = episode.AirDate; episodeToUpdate.AirDate = episode.AirDate;
if(!String.IsNullOrWhiteSpace(series.AirTime) && episodeToUpdate.AirDate.HasValue)
{
episodeToUpdate.AirDate = episodeToUpdate.AirDate.Value.Add(Convert.ToDateTime(series.AirTime).TimeOfDay)
.AddHours(series.UtcOffset * -1);
}
successCount++; successCount++;
} }
catch (Exception e) catch (Exception e)

View File

@ -1,4 +1,5 @@
using System.Linq; using System.Collections.Generic;
using System.Linq;
using System; using System;
using NzbDrone.Core.Datastore; using NzbDrone.Core.Datastore;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
@ -8,8 +9,6 @@ using Sqo.Attributes;
namespace NzbDrone.Core.Tv namespace NzbDrone.Core.Tv
{ {
public enum SeriesType public enum SeriesType
{ {
Standard =0, Standard =0,
@ -17,71 +16,44 @@ namespace NzbDrone.Core.Tv
Anime = 2, Anime = 2,
} }
public class Series : ModelBase public class Series : ModelBase
{ {
public int TvDbId { get; set; } public int TvDbId { get; set; }
public string Title { get; set; } public string Title { get; set; }
public string CleanTitle { get; set; } public string CleanTitle { get; set; }
public string Status { get; set; } public string Status { get; set; }
[Text] [Text]
public string Overview { get; set; } public string Overview { get; set; }
//public DayOfWeek? AirsDayOfWeek { get; set; }
public String AirTime { get; set; } public String AirTime { get; set; }
public string Language { get; set; } public string Language { get; set; }
public string Path { get; set; } public string Path { get; set; }
public bool Monitored { get; set; } public bool Monitored { get; set; }
public int QualityProfileId { get; set; }
public virtual int QualityProfileId { get; set; }
public bool SeasonFolder { get; set; } public bool SeasonFolder { get; set; }
public DateTime? LastInfoSync { get; set; } public DateTime? LastInfoSync { get; set; }
public DateTime? LastDiskSync { get; set; } public DateTime? LastDiskSync { get; set; }
public int Runtime { get; set; } public int Runtime { get; set; }
public string BannerUrl { get; set; } public string BannerUrl { get; set; }
public SeriesType SeriesType { get; set; } public SeriesType SeriesType { get; set; }
public BacklogSettingType BacklogSetting { get; set; } public BacklogSettingType BacklogSetting { get; set; }
public string Network { get; set; } public string Network { get; set; }
public DateTime? CustomStartDate { get; set; } public DateTime? CustomStartDate { get; set; }
public bool UseSceneNumbering { get; set; } public bool UseSceneNumbering { get; set; }
public int TvRageId { get; set; } public int TvRageId { get; set; }
public string TvRageTitle { get; set; } public string TvRageTitle { get; set; }
//Todo: This should be a double since there are timezones that aren't on a full hour offset //Todo: This should be a double since there are timezones that aren't on a full hour offset
public int UtcOffset { get; set; } public int UtcOffset { get; set; }
public DateTime? FirstAired { get; set; } public DateTime? FirstAired { get; set; }
public bool Hidden { get; set; }
public QualityProfile QualityProfile { get; set; } public QualityProfile QualityProfile { get; set; }
public int EpisodeCount { get; set; } public int EpisodeCount { get; set; }
public int EpisodeFileCount { get; set; } public int EpisodeFileCount { get; set; }
public int SeasonCount { get; set; } public int SeasonCount { get; set; }
public DateTime? NextAiring { get; set; } public DateTime? NextAiring { get; set; }
public List<Episode> Episodes { get; set; }
} }
} }

View File

@ -10,6 +10,7 @@ using NzbDrone.Core.Datastore;
using NzbDrone.Core.Model; using NzbDrone.Core.Model;
using NzbDrone.Core.Providers; using NzbDrone.Core.Providers;
using NzbDrone.Core.Providers.Core; using NzbDrone.Core.Providers.Core;
using NzbDrone.Core.Qualities;
using NzbDrone.Core.Tv.Events; using NzbDrone.Core.Tv.Events;
namespace NzbDrone.Core.Tv namespace NzbDrone.Core.Tv
@ -31,6 +32,7 @@ namespace NzbDrone.Core.Tv
private readonly MetadataProvider _metadataProvider; private readonly MetadataProvider _metadataProvider;
private readonly TvRageMappingProvider _tvRageMappingProvider; private readonly TvRageMappingProvider _tvRageMappingProvider;
private readonly IEventAggregator _eventAggregator; private readonly IEventAggregator _eventAggregator;
private readonly IQualityProfileService _qualityProfileService;
private static readonly Logger logger = LogManager.GetCurrentClassLogger(); private static readonly Logger logger = LogManager.GetCurrentClassLogger();
@ -38,7 +40,7 @@ namespace NzbDrone.Core.Tv
public SeriesService(ISeriesRepository seriesRepository, IConfigService configServiceService, public SeriesService(ISeriesRepository seriesRepository, IConfigService configServiceService,
TvDbProvider tvDbProviderProvider, SceneMappingProvider sceneNameMappingProvider, MetadataProvider metadataProvider, TvDbProvider tvDbProviderProvider, SceneMappingProvider sceneNameMappingProvider, MetadataProvider metadataProvider,
TvRageMappingProvider tvRageMappingProvider, IEventAggregator eventAggregator) TvRageMappingProvider tvRageMappingProvider, IEventAggregator eventAggregator, IQualityProfileService qualityProfileService)
{ {
_seriesRepository = seriesRepository; _seriesRepository = seriesRepository;
_configService = configServiceService; _configService = configServiceService;
@ -47,6 +49,7 @@ namespace NzbDrone.Core.Tv
_metadataProvider = metadataProvider; _metadataProvider = metadataProvider;
_tvRageMappingProvider = tvRageMappingProvider; _tvRageMappingProvider = tvRageMappingProvider;
_eventAggregator = eventAggregator; _eventAggregator = eventAggregator;
_qualityProfileService = qualityProfileService;
} }
@ -63,7 +66,6 @@ namespace NzbDrone.Core.Tv
series.Title = tvDbSeries.SeriesName; series.Title = tvDbSeries.SeriesName;
series.AirTime = CleanAirsTime(tvDbSeries.AirsTime); series.AirTime = CleanAirsTime(tvDbSeries.AirsTime);
//series.AirsDayOfWeek = tvDbSeries.AirsDayOfWeek;
series.Overview = tvDbSeries.Overview; series.Overview = tvDbSeries.Overview;
series.Status = tvDbSeries.Status; series.Status = tvDbSeries.Status;
series.Language = tvDbSeries.Language != null ? tvDbSeries.Language.Abbriviation : string.Empty; series.Language = tvDbSeries.Language != null ? tvDbSeries.Language.Abbriviation : string.Empty;
@ -114,8 +116,7 @@ namespace NzbDrone.Core.Tv
logger.Info("Adding Series [{0}] Path: [{1}]", tvDbSeriesId, path); logger.Info("Adding Series [{0}] Path: [{1}]", tvDbSeriesId, path);
Ensure.That(() => tvDbSeriesId).IsGreaterThan(0); Ensure.That(() => tvDbSeriesId).IsGreaterThan(0);
//Todo: We can't validate the title if we're passing in an empty string Ensure.That(() => title).IsNotNullOrWhiteSpace();
//Ensure.That(() => title).IsNotNullOrWhiteSpace();
Ensure.That(() => path).IsNotNullOrWhiteSpace(); Ensure.That(() => path).IsNotNullOrWhiteSpace();
var repoSeries = new Series(); var repoSeries = new Series();
@ -127,6 +128,7 @@ namespace NzbDrone.Core.Tv
if (qualityProfileId == 0) if (qualityProfileId == 0)
repoSeries.QualityProfileId = _configService.DefaultQualityProfile; repoSeries.QualityProfileId = _configService.DefaultQualityProfile;
repoSeries.QualityProfile = _qualityProfileService.Get(repoSeries.QualityProfileId);
repoSeries.SeasonFolder = _configService.UseSeasonFolder; repoSeries.SeasonFolder = _configService.UseSeasonFolder;
repoSeries.BacklogSetting = BacklogSettingType.Inherit; repoSeries.BacklogSetting = BacklogSettingType.Inherit;
@ -138,7 +140,6 @@ namespace NzbDrone.Core.Tv
_eventAggregator.Publish(new SeriesAddedEvent(repoSeries)); _eventAggregator.Publish(new SeriesAddedEvent(repoSeries));
} }
public void UpdateFromSeriesEditor(IList<Series> editedSeries) public void UpdateFromSeriesEditor(IList<Series> editedSeries)
{ {
var allSeries = _seriesRepository.All(); var allSeries = _seriesRepository.All();