diff --git a/tracks/app/controllers/feed_controller.rb b/tracks/app/controllers/feed_controller.rb index fc0c7f64..c934e144 100644 --- a/tracks/app/controllers/feed_controller.rb +++ b/tracks/app/controllers/feed_controller.rb @@ -34,6 +34,20 @@ class FeedController < ApplicationController end @headers["Content-Type"] = "text/plain; charset=utf-8" end + + # Builds an iCal compatible export of uncompleted todos + # so that each action forms a VTODO in your iCal calendar. + # Due dates are supported, and notes are included. + # + def ical + prepare_for_feed + if @params.key?('context') + @contexts = [ @user.contexts.find(@params['context']) ] + else + @contexts = @user.contexts.find_all_by_hide(false, "position ASC") + end + @headers["Content-Type"] = "text/plain; charset=utf-8" + end protected diff --git a/tracks/app/helpers/todo_helper.rb b/tracks/app/helpers/todo_helper.rb index 56d7a3c2..25c60f53 100644 --- a/tracks/app/helpers/todo_helper.rb +++ b/tracks/app/helpers/todo_helper.rb @@ -121,4 +121,10 @@ module TodoHelper link_to('TXT', linkoptions, :title => "Plain text feed" ) end + def ical_feed_link(options = {}) + linkoptions = {:controller => 'feed', :action => 'ical', :name => "#{@user.login}", :token => "#{@user.word}"} + linkoptions.merge!(options) + link_to('iCal', linkoptions, :title => "iCal feed") + end + end diff --git a/tracks/app/views/feed/ical.rhtml b/tracks/app/views/feed/ical.rhtml new file mode 100644 index 00000000..b0775335 --- /dev/null +++ b/tracks/app/views/feed/ical.rhtml @@ -0,0 +1,35 @@ +BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//rousette.org.uk//Tracks 1.04//EN +CALSCALE:GREGORIAN +METHOD:PUBLISH +BEGIN:VTIMEZONE +TZID:Europe/London +LAST-MODIFIED:<%= Time.now.strftime("%Y%m%dT%H%M%SZ") %> +BEGIN:DAYLIGHT +DTSTART:20060326T020000 +TZOFFSETTO:+0100 +TZOFFSETFROM:+0000 +TZNAME:BST +END:DAYLIGHT +BEGIN:STANDARD +DTSTART:20061029T020000 +TZOFFSETTO:+0000 +TZOFFSETFROM:+0100 +TZNAME:GMT +END:STANDARD +END:VTIMEZONE +<% for @todo in @todos -%> +BEGIN:VTODO +DTSTAMP:<%= @todo.created_at.strftime("%Y%m%dT%H%M%SZ") %> +DTSTART;VALUE=DATE:<%= @todo.created_at.strftime("%Y%m%d") %> +SUMMARY:<%= @todo.description %> +<% if @todo.notes? -%> +DESCRIPTION:<%= @todo.notes %> +<% end -%> +<% if @todo.due -%> +DUE;VALUE=DATE:<%= @todo.due.strftime("%Y%m%d") %> +<% end -%> +END:VTODO +<% end -%> +END:VCALENDAR \ No newline at end of file diff --git a/tracks/app/views/todo/feeds.rhtml b/tracks/app/views/todo/feeds.rhtml index 9ecb0744..6e542e6b 100644 --- a/tracks/app/views/todo/feeds.rhtml +++ b/tracks/app/views/todo/feeds.rhtml @@ -12,6 +12,7 @@
<%= image_tag("feed-icon", :size => "16X16", :border => 0)%>
RSS Feed
TXT
Plain Text Feed
+
iCal
iCal feed

Note: All feeds show only actions that have not been marked as done.

@@ -19,21 +20,25 @@
  • <%= rss_feed_link({ :limit => 15 }) %> <%= text_feed_link({ :limit => 15 }) %> + <%= ical_feed_link({ :limit => 15 }) %> Last 15 actions
  • <%= rss_feed_link %> <%= text_feed_link %> + <%= ical_feed_link %> All actions
  • <%= rss_feed_link({ :due => 0 }) %> <%= text_feed_link({ :due => 0 }) %> + <%= ical_feed_link({ :due => 0 }) %> Actions due today or earlier
  • <%= rss_feed_link({ :due => 6 }) %> <%= text_feed_link({ :due => 6 }) %> + <%= ical_feed_link({ :due => 6 }) %> Actions due in 7 days or earlier
  • Feeds for uncompleted actions in a specific context:

    @@ -42,6 +47,7 @@
  • <%= rss_feed_link({ :context => context }) %> <%= text_feed_link({ :context => context }) %> + <%= ical_feed_link({ :context => context }) %> Next actions in <%=h context.name %>
  • <% end %> @@ -53,6 +59,7 @@
  • <%= rss_feed_link({ :project => project }) %> <%= text_feed_link({ :project => project }) %> + <%= ical_feed_link({ :project => project }) %> Next actions for <%=h project.name %>
  • <% end %> diff --git a/tracks/config/routes.rb b/tracks/config/routes.rb index ceaf1289..534a40e9 100644 --- a/tracks/config/routes.rb +++ b/tracks/config/routes.rb @@ -50,8 +50,7 @@ ActionController::Routing::Routes.draw do |map| map.connect 'notes', :controller => 'note', :action => 'index' # Feed Routes - map.connect 'feed/:action/:name/:token', :controller => 'feed' - + map.connect 'feed/:action/:name/:token', :controller => 'feed' #map.connect 'add_item', :controller => 'todo', :action => 'add_item'