mirror of https://github.com/Sonarr/Sonarr
Calendar colouring, upcoming list shows yesterday
Cleaned up series file a bit. Added spoon for common sugar tasks.
This commit is contained in:
parent
14cf5bf3cc
commit
da2c0d1d65
|
@ -39,7 +39,8 @@ namespace NzbDrone.Api
|
|||
.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.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
|
||||
Mapper.CreateMap<Episode, CalendarResource>()
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace NzbDrone.Api.Calendar
|
|||
|
||||
private Response GetEpisodesBetweenStartAndEndDate()
|
||||
{
|
||||
var start = DateTime.Today;
|
||||
var start = DateTime.Today.AddDays(-1);
|
||||
var end = DateTime.Today.AddDays(7);
|
||||
|
||||
var queryStart = Request.Query.Start;
|
||||
|
|
|
@ -4,6 +4,7 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using NzbDrone.Api.QualityProfiles;
|
||||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Qualities;
|
||||
|
||||
namespace NzbDrone.Api.Series
|
||||
{
|
||||
|
|
|
@ -20,6 +20,7 @@ define(['app', 'Calendar/CalendarItemView'], function (app) {
|
|||
allDayDefault: false,
|
||||
ignoreTimezone: false,
|
||||
weekMode: 'variable',
|
||||
timeFormat: 'h(:mm)tt',
|
||||
header: {
|
||||
left: 'prev,next today',
|
||||
center: 'title',
|
||||
|
@ -31,6 +32,9 @@ define(['app', 'Calendar/CalendarItemView'], function (app) {
|
|||
},
|
||||
events: this.getEvents,
|
||||
eventRender: function (event, element) {
|
||||
$(element).addClass(event.statusLevel);
|
||||
$(element).children('.fc-event-inner').addClass(event.statusLevel);
|
||||
|
||||
element.popover({
|
||||
title: '{seriesTitle} - {season}x{episode} - {episodeTitle}'.assign({
|
||||
seriesTitle: event.seriesTitle,
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
<h4>{{month}}</h4>
|
||||
</div>
|
||||
<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>
|
||||
|
|
|
@ -33,11 +33,16 @@
|
|||
if (currentTime.isBetween(start, end))
|
||||
return 'warning';
|
||||
|
||||
if (status === 'Missing') return 'danger';
|
||||
if (start.isBefore(currentTime) || status === 'Missing')
|
||||
return 'danger';
|
||||
|
||||
if (status === 'Ready') return 'success';
|
||||
|
||||
return 'info';
|
||||
}
|
||||
return 'primary';
|
||||
},
|
||||
bestDateString: function () {
|
||||
return bestDateString(this.get('start'));
|
||||
},
|
||||
},
|
||||
defaults: {
|
||||
status: 0
|
||||
|
|
|
@ -824,12 +824,51 @@ ul.stat-list {
|
|||
border-color: #EEE;
|
||||
}
|
||||
|
||||
#calendar .fc-event-skin {
|
||||
background-color: #007ccd;
|
||||
border: 1px solid #007ccd;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
}
|
||||
#calendar .fc-event-skin {
|
||||
background-color: #007ccd;
|
||||
border: 1px solid #007ccd;
|
||||
border-radius: 4px;
|
||||
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 ============== */
|
||||
.tag {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
define(['app', 'Shared/ModalRegion', 'AddSeries/AddSeriesLayout', 'Series/SeriesCollectionView',
|
||||
'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({
|
||||
|
||||
|
|
|
@ -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();
|
||||
});
|
|
@ -34,9 +34,11 @@
|
|||
<div id="in-nav">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<a id="logo" href="/">
|
||||
<h4>Nzb<strong>Drone</strong></h4>
|
||||
</a>
|
||||
<div class=span2>
|
||||
<a id="logo" href="/">
|
||||
<h4>Nzb<strong>Drone</strong></h4>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -109,6 +111,7 @@
|
|||
<script src="/static/Mixins/backbone.marionette.templates.js"></script>
|
||||
<script src="/static/Mixins/backbone.ajax.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 src="/static/Routing.js"></script>
|
||||
|
|
|
@ -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}');
|
||||
}
|
|
@ -3,18 +3,7 @@
|
|||
|
||||
mutators: {
|
||||
bestDateString: function () {
|
||||
var dateSource = 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}');
|
||||
return bestDateString(this.get('nextAiring'));
|
||||
},
|
||||
|
||||
percentOfEpisodes: function () {
|
||||
|
|
|
@ -182,7 +182,6 @@ namespace NzbDrone.Core.Tv
|
|||
|
||||
var tvdbEpisodes = _tvDbProvider.GetEpisodes(series.TvDbId);
|
||||
|
||||
|
||||
var seriesEpisodes = GetEpisodeBySeries(series.Id);
|
||||
var updateList = new List<Episode>();
|
||||
var newList = new List<Episode>();
|
||||
|
@ -237,10 +236,15 @@ namespace NzbDrone.Core.Tv
|
|||
episodeToUpdate.SeasonNumber = episode.SeasonNumber;
|
||||
episodeToUpdate.AbsoluteEpisodeNumber = episode.AbsoluteEpisodeNumber;
|
||||
episodeToUpdate.Title = episode.Title;
|
||||
|
||||
episodeToUpdate.Overview = episode.Overview;
|
||||
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++;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Model;
|
||||
|
@ -8,8 +9,6 @@ using Sqo.Attributes;
|
|||
|
||||
namespace NzbDrone.Core.Tv
|
||||
{
|
||||
|
||||
|
||||
public enum SeriesType
|
||||
{
|
||||
Standard =0,
|
||||
|
@ -17,71 +16,44 @@ namespace NzbDrone.Core.Tv
|
|||
Anime = 2,
|
||||
}
|
||||
|
||||
|
||||
public class Series : ModelBase
|
||||
{
|
||||
public int TvDbId { get; set; }
|
||||
|
||||
public string Title { get; set; }
|
||||
|
||||
public string CleanTitle { get; set; }
|
||||
|
||||
public string Status { get; set; }
|
||||
|
||||
[Text]
|
||||
public string Overview { get; set; }
|
||||
|
||||
//public DayOfWeek? AirsDayOfWeek { get; set; }
|
||||
|
||||
public String AirTime { get; set; }
|
||||
|
||||
public string Language { get; set; }
|
||||
|
||||
public string Path { get; set; }
|
||||
|
||||
public bool Monitored { get; set; }
|
||||
|
||||
public virtual int QualityProfileId { get; set; }
|
||||
|
||||
public int QualityProfileId { get; set; }
|
||||
public bool SeasonFolder { get; set; }
|
||||
|
||||
public DateTime? LastInfoSync { get; set; }
|
||||
|
||||
public DateTime? LastDiskSync { get; set; }
|
||||
|
||||
public int Runtime { get; set; }
|
||||
|
||||
public string BannerUrl { get; set; }
|
||||
|
||||
public SeriesType SeriesType { get; set; }
|
||||
|
||||
public BacklogSettingType BacklogSetting { get; set; }
|
||||
|
||||
public string Network { get; set; }
|
||||
|
||||
public DateTime? CustomStartDate { get; set; }
|
||||
|
||||
public bool UseSceneNumbering { get; set; }
|
||||
|
||||
public int TvRageId { 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
|
||||
public int UtcOffset { get; set; }
|
||||
|
||||
public DateTime? FirstAired { get; set; }
|
||||
|
||||
public bool Hidden { get; set; }
|
||||
|
||||
public QualityProfile QualityProfile { get; set; }
|
||||
|
||||
public int EpisodeCount { get; set; }
|
||||
|
||||
public int EpisodeFileCount { get; set; }
|
||||
|
||||
public int SeasonCount { get; set; }
|
||||
|
||||
public DateTime? NextAiring { get; set; }
|
||||
|
||||
public List<Episode> Episodes { get; set; }
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ using NzbDrone.Core.Datastore;
|
|||
using NzbDrone.Core.Model;
|
||||
using NzbDrone.Core.Providers;
|
||||
using NzbDrone.Core.Providers.Core;
|
||||
using NzbDrone.Core.Qualities;
|
||||
using NzbDrone.Core.Tv.Events;
|
||||
|
||||
namespace NzbDrone.Core.Tv
|
||||
|
@ -31,6 +32,7 @@ namespace NzbDrone.Core.Tv
|
|||
private readonly MetadataProvider _metadataProvider;
|
||||
private readonly TvRageMappingProvider _tvRageMappingProvider;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly IQualityProfileService _qualityProfileService;
|
||||
|
||||
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
|
||||
|
||||
|
@ -38,7 +40,7 @@ namespace NzbDrone.Core.Tv
|
|||
|
||||
public SeriesService(ISeriesRepository seriesRepository, IConfigService configServiceService,
|
||||
TvDbProvider tvDbProviderProvider, SceneMappingProvider sceneNameMappingProvider, MetadataProvider metadataProvider,
|
||||
TvRageMappingProvider tvRageMappingProvider, IEventAggregator eventAggregator)
|
||||
TvRageMappingProvider tvRageMappingProvider, IEventAggregator eventAggregator, IQualityProfileService qualityProfileService)
|
||||
{
|
||||
_seriesRepository = seriesRepository;
|
||||
_configService = configServiceService;
|
||||
|
@ -47,6 +49,7 @@ namespace NzbDrone.Core.Tv
|
|||
_metadataProvider = metadataProvider;
|
||||
_tvRageMappingProvider = tvRageMappingProvider;
|
||||
_eventAggregator = eventAggregator;
|
||||
_qualityProfileService = qualityProfileService;
|
||||
}
|
||||
|
||||
|
||||
|
@ -63,7 +66,6 @@ namespace NzbDrone.Core.Tv
|
|||
|
||||
series.Title = tvDbSeries.SeriesName;
|
||||
series.AirTime = CleanAirsTime(tvDbSeries.AirsTime);
|
||||
//series.AirsDayOfWeek = tvDbSeries.AirsDayOfWeek;
|
||||
series.Overview = tvDbSeries.Overview;
|
||||
series.Status = tvDbSeries.Status;
|
||||
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);
|
||||
|
||||
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();
|
||||
|
||||
var repoSeries = new Series();
|
||||
|
@ -127,6 +128,7 @@ namespace NzbDrone.Core.Tv
|
|||
if (qualityProfileId == 0)
|
||||
repoSeries.QualityProfileId = _configService.DefaultQualityProfile;
|
||||
|
||||
repoSeries.QualityProfile = _qualityProfileService.Get(repoSeries.QualityProfileId);
|
||||
repoSeries.SeasonFolder = _configService.UseSeasonFolder;
|
||||
repoSeries.BacklogSetting = BacklogSettingType.Inherit;
|
||||
|
||||
|
@ -138,7 +140,6 @@ namespace NzbDrone.Core.Tv
|
|||
_eventAggregator.Publish(new SeriesAddedEvent(repoSeries));
|
||||
}
|
||||
|
||||
|
||||
public void UpdateFromSeriesEditor(IList<Series> editedSeries)
|
||||
{
|
||||
var allSeries = _seriesRepository.All();
|
||||
|
|
Loading…
Reference in New Issue