New: iCal calendar feed.

pull/65/head
Taloth Saldono 11 years ago committed by Taloth
parent cf1e0a4946
commit 794c09c17a

@ -23,7 +23,7 @@ namespace NzbDrone.Api.Calendar
private Response GetCalendarFeed() private Response GetCalendarFeed()
{ {
var start = DateTime.Today.Subtract(TimeSpan.FromDays(7)); var start = DateTime.Today.AddDays(-7);
var end = DateTime.Today.AddDays(28); var end = DateTime.Today.AddDays(28);
var queryStart = Request.Query.Start; var queryStart = Request.Query.Start;
@ -35,9 +35,7 @@ namespace NzbDrone.Api.Calendar
var episodes = _episodeService.EpisodesBetweenDates(start, end); var episodes = _episodeService.EpisodesBetweenDates(start, end);
var icalCalendar = new iCalendar(); var icalCalendar = new iCalendar();
foreach (var series in episodes.GroupBy(v => v.Series)) foreach (var episode in episodes.OrderBy(v => v.AirDateUtc.Value))
{
foreach (var episode in series)
{ {
var occurrence = icalCalendar.Create<Event>(); var occurrence = icalCalendar.Create<Event>();
occurrence.UID = "NzbDrone_episode_" + episode.Id.ToString(); occurrence.UID = "NzbDrone_episode_" + episode.Id.ToString();
@ -58,7 +56,6 @@ namespace NzbDrone.Api.Calendar
break; break;
} }
} }
}
var serializer = new DDay.iCal.Serialization.iCalendar.SerializerFactory().Build(icalCalendar.GetType(), new DDay.iCal.Serialization.SerializationContext()) as DDay.iCal.Serialization.IStringSerializer; var serializer = new DDay.iCal.Serialization.iCalendar.SerializerFactory().Build(icalCalendar.GetType(), new DDay.iCal.Serialization.SerializationContext()) as DDay.iCal.Serialization.IStringSerializer;
var icalendar = serializer.SerializeToString(icalCalendar); var icalendar = serializer.SerializeToString(icalCalendar);

@ -2,15 +2,24 @@
define( define(
[ [
'marionette', 'marionette',
], function (Marionette) { 'System/StatusModel',
'Mixins/CopyToClipboard'
], function (Marionette, StatusModel) {
return Marionette.Layout.extend({ return Marionette.Layout.extend({
template: 'Calendar/CalendarFeedViewTemplate', template: 'Calendar/CalendarFeedViewTemplate',
onRender: function() { ui: {
// hackish way to determine the correct url, as using urlBase seems to only work for reverse proxies or so icalUrl : '.x-ical-url',
var ics = '//' + window.location.host + '/feed/calendar/NzbDrone.ics'; icalCopy : '.x-ical-copy'
this.$('#ical-url').val(window.location.protocol + ics); },
this.$('#ical-subscribe-button').attr('href', 'webcal:' + ics);
templateHelpers: {
icalHttpUrl : window.location.protocol + '//' + window.location.host + StatusModel.get('urlBase') + '/feed/calendar/NzbDrone.ics',
icalWebCalUrl : 'webcal://' + window.location.host + StatusModel.get('urlBase') + '/feed/calendar/NzbDrone.ics'
},
onShow: function () {
this.ui.icalCopy.copyToClipboard(this.ui.icalUrl);
} }
}); });
}); });

@ -7,14 +7,17 @@
<div> <div>
<div class="form-horizontal"> <div class="form-horizontal">
<div class="control-group"> <div class="control-group">
<label class="control-label" for="ical-url">iCal feed</label> <label class="control-label">iCal feed</label>
<div class="controls"> <div class="controls ical-url">
<input type="text" id="ical-url" class="x-ical-url" value="/feed/calendar/NzbDrone.ics" name="ical-url"> <div class="input-append">
<input type="text" class="x-ical-url" value="{{icalHttpUrl}}" readonly="readonly" />
<button class="btn btn-icon-only x-ical-copy" title="Copy to clipboard"><i class="icon-copy"></i></button>
<a class="btn btn-icon-only no-router" title="Subscribe" href="{{icalWebCalUrl}}" target="_blank"><i class="icon-calendar-empty"></i></a>
</div>
<span class="help-inline"> <span class="help-inline">
<i class="icon-nd-form-info" title="copy this url into your clients subscription form or use the subscribe now link if you have a webcal protocol handler installed"/> <i class="icon-nd-form-info" title="Copy this url into your clients subscription form or use the subscribe button if your browser support webcal"/>
</span> </span>
or <a href="webcal:///feed/calendar/NzbDrone.ics" id="ical-subscribe-button">subscribe now!</a>
</div> </div>
</div> </div>
</div> </div>

@ -162,9 +162,13 @@
.ical .ical
{ {
color: @btnInverseBackground; color: @btnInverseBackground;
cursor: pointer;
} }
#ical-url .ical-url {
{
width: 370px; input {
width : 440px;
cursor : text;
}
} }

@ -29,17 +29,21 @@ define(
return; return;
} }
event.preventDefault();
var href = event.target.getAttribute('href'); var href = event.target.getAttribute('href');
if (!href && $target.closest('a') && $target.closest('a')[0]) { if (!href && $target.closest('a') && $target.closest('a')[0]) {
var linkElement = $target.closest('a')[0]; var linkElement = $target.closest('a')[0];
if ($(linkElement).hasClass('no-router')) {
return;
}
href = linkElement.getAttribute('href'); href = linkElement.getAttribute('href');
} }
event.preventDefault();
if (!href) { if (!href) {
throw 'couldn\'t find route target'; throw 'couldn\'t find route target';
} }

Loading…
Cancel
Save