diff --git a/tracks/app/controllers/application.rb b/tracks/app/controllers/application.rb index 9fb16a6f..6b42a528 100644 --- a/tracks/app/controllers/application.rb +++ b/tracks/app/controllers/application.rb @@ -13,7 +13,7 @@ class ApplicationController < ActionController::Base helper :application include LoginSystem - + layout 'standard' before_filter :set_session_expiration @@ -21,6 +21,9 @@ class ApplicationController < ActionController::Base after_filter :set_charset + include ActionView::Helpers::TextHelper + helper_method :format_date, :markdown + # By default, sets the charset to UTF-8 if it isn't already set def set_charset headers["Content-Type"] ||= "text/html; charset=UTF-8" @@ -78,13 +81,35 @@ class ApplicationController < ActionController::Base end def count_undone_todos(todos_parent) - if (todos_parent.is_a?(Project) && todos_parent.hidden?) + if todos_parent.nil? + count = 0 + elsif (todos_parent.is_a?(Project) && todos_parent.hidden?) count = eval "@project_project_hidden_todo_counts[#{todos_parent.id}]" else count = eval "@#{todos_parent.class.to_s.downcase}_not_done_counts[#{todos_parent.id}]" end - count = 0 if count == nil - count + count || 0 + end + + # Convert a date object to the format specified + # in config/settings.yml + # + def format_date(date) + if date + date_format = @user.prefs.date_format + formatted_date = date.strftime("#{date_format}") + else + formatted_date = '' + end + formatted_date + end + + # Uses RedCloth to transform text using either Textile or Markdown + # Need to require redcloth above + # RedCloth 3.0 or greater is needed to use Markdown, otherwise it only handles Textile + # + def markdown(text) + RedCloth.new(text).to_html end protected diff --git a/tracks/app/controllers/feed_controller.rb b/tracks/app/controllers/feed_controller.rb deleted file mode 100644 index badce178..00000000 --- a/tracks/app/controllers/feed_controller.rb +++ /dev/null @@ -1,133 +0,0 @@ -# Produces an feeds of the next actions, both RSS and plain text -# -class FeedController < ApplicationController - - helper :feed - layout nil - - session :disabled => true # Prevents session control from interfering with feed - - skip_before_filter :login_required - before_filter :check_token_against_user_word - before_filter :prepare_for_feed, :only => [:rss, :text, :ical] - before_filter :identify_contexts, :only => [:text, :ical] - - # Build an RSS feed - def rss - headers["Content-Type"] = "text/xml; charset=utf-8" - end - - # Builds a plain text page listing incomplete next actions, - # grouped by context (contexts are sorted by position, as on the home page). - # Showing notes doesn't make much sense here so they are omitted. - # Hidden contexts are also hidden in the text view - # You can use this with GeekTool to get your next actions - # on the desktop: - # curl [url from "TXT" link on todo/list] - # - def text - headers["Content-Type"] = "text/plain; charset=utf-8" - end - - # Builds an iCal compatible export of incomplete todos - # so that each action forms a VTODO in your iCal calendar. - # Due dates are supported, and notes are included. - # - def ical - headers["Content-Type"] = "text/calendar" - end - -protected - - # Check whether the token in the URL matches the word in the User's table - def check_token_against_user_word - @user = User.find_by_login( params['login'] ) - unless ( params['token'] == @user.word) - render :text => "Sorry, you don't have permission to view this page." - return false - end - end - - def identify_contexts - if params.key?('context') - @contexts = [ @user.contexts.find_by_params(params) ] - else - @contexts = @user.contexts.find_all_by_hide(false, "position ASC") - end - end - - def prepare_for_feed - condition_builder = FindConditionBuilder.new - options = Hash.new - - if params.key?('done') - condition_builder.add 'todos.state = ?', 'completed' - else - condition_builder.add 'todos.state = ?', 'active' - end - - if params.key?('limit') - options[:limit] = limit = params['limit'] - @description = limit ? "Lists the last #{limit} incomplete next actions" : "Lists incomplete next actions" - end - @title = "Tracks - Next Actions" - @description = "Filter: " - - if params.key?('due') - due_within = params['due'].to_i - due_within_when = @user.time + due_within.days - condition_builder.add('todos.due <= ?', due_within_when) - due_within_date_s = due_within_when.strftime("%Y-%m-%d") - @title << " due today" if (due_within == 0) - @title << " due within a week" if (due_within == 6) - @description << " with a due date #{due_within_date_s} or earlier" - end - - if params.key?('done') - done_in_last = params['done'].to_i - condition_builder.add('todos.completed_at >= ?', @user.time - done_in_last.days) - @title << " actions completed" - @description << " in the last #{done_in_last.to_s} days" - end - - if params.key?('context') - context = @user.contexts.find_by_params(params) - condition_builder.add('todos.context_id = ?', context.id) - @title << " in #{context.name}" - @description << " in context '#{context.name}'" - end - - if params.key?('project') - project = @user.projects.find_by_params(params) - condition_builder.add('todos.project_id = ?', project.id) - @title << " for #{project.name}" - @description << " for project '#{project.name}'" - end - - options[:conditions] = condition_builder.to_conditions - options[:order] = "todos.due IS NULL, todos.due ASC, todos.created_at ASC" - options[:include] = :project - - @todos = @user.todos.find(:all, options ) - - end - - class FindConditionBuilder - - def initialize - @queries = Array.new - @params = Array.new - end - - def add(query, param) - @queries << query - @params << param - end - - def to_conditions - [@queries.join(' AND ')] + @params - end - end - - -end diff --git a/tracks/app/controllers/projects_controller.rb b/tracks/app/controllers/projects_controller.rb index df042b5e..5ed1149c 100644 --- a/tracks/app/controllers/projects_controller.rb +++ b/tracks/app/controllers/projects_controller.rb @@ -138,14 +138,15 @@ class ProjectsController < ApplicationController def render_rss_feed lambda do render_rss_feed_for @projects, :feed => Project.feed_options(@user), - :item => { :description => lambda { |p| p.summary(count_undone_todos_phrase(p)) } } + :item => { :title => :name, :description => lambda { |p| summary(p) } } end end def render_atom_feed lambda do render_atom_feed_for @projects, :feed => Project.feed_options(@user), - :item => { :description => lambda { |p| p.summary(count_undone_todos_phrase(p)) }, + :item => { :description => lambda { |p| summary(p) }, + :title => :name, :author => lambda { |p| nil } } end end @@ -181,4 +182,13 @@ class ProjectsController < ApplicationController init_data_for_sidebar end + def summary(project) + project_description = '' + project_description += sanitize(markdown( project.description )) unless project.description.blank? + project_description += "

#{count_undone_todos_phrase(p)}. " + project_description += "Project is #{project.state}." + project_description += "

" + project_description + end + end diff --git a/tracks/app/controllers/todos_controller.rb b/tracks/app/controllers/todos_controller.rb index e900b3bb..20e508de 100644 --- a/tracks/app/controllers/todos_controller.rb +++ b/tracks/app/controllers/todos_controller.rb @@ -3,33 +3,28 @@ class TodosController < ApplicationController helper :todos append_before_filter :init, :except => [ :destroy, :completed, :completed_archive, :check_deferred ] + skip_before_filter :login_required, :only => [:index] + prepend_before_filter :login_or_feed_token_required, :only => [:index] + session :off, :only => :index, :if => Proc.new { |req| is_feed_request(req) } + layout 'standard' - # Main method for listing tasks - # Set page title, and fill variables with contexts and done and not-done tasks - # Number of completed actions to show is determined by a setting in settings.yml def index @projects = @user.projects.find(:all, :include => [ :todos ]) @contexts = @user.contexts.find(:all, :include => [ :todos ]) - - @page_title = "TRACKS::List tasks" - - # If you've set no_completed to zero, the completed items box - # isn't shown on the home page - max_completed = @user.prefs.show_number_completed - @done = @user.completed_todos.find(:all, :limit => max_completed, :include => [ :context, :project, :tags ]) unless max_completed == 0 - + @contexts_to_show = @contexts.reject {|x| x.hide? } - # Set count badge to number of not-done, not hidden context items - @count = @todos.reject { |x| !x.active? || x.context.hide? }.size - - respond_to do |wants| - wants.html - wants.xml { render :action => 'list.rxml', :layout => false } + respond_to do |format| + format.html &render_todos_html + format.xml { render :action => 'list.rxml', :layout => false } + format.rss &render_rss_feed + format.atom &render_atom_feed + format.text &render_text_feed + format.ics &render_ical_feed end end - + def create @todo = @user.todos.build p = params['request'] || params @@ -100,7 +95,7 @@ class TodosController < ApplicationController # def toggle_check @todo = check_user_return_todo - @todo.toggle_completion() + @todo.toggle_completion! @saved = @todo.save respond_to do |format| format.js do @@ -279,13 +274,89 @@ class TodosController < ApplicationController init_data_for_sidebar init_todos end - - def init_todos - # Exclude hidden projects from count on home page - @todos = @user.todos.find(:all, :conditions => ['todos.state = ? or todos.state = ?', 'active', 'complete'], :include => [ :project, :context, :tags ]) - # Exclude hidden projects from the home page - @not_done_todos = @user.todos.find(:all, :conditions => ['todos.state = ?', 'active'], :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", :include => [ :project, :context, :tags ]) + def with_feed_query_scope(&block) + unless TodosController.is_feed_request(request) + yield + return + end + + condition_builder = FindConditionBuilder.new + options = Hash.new + + if params.key?('done') + condition_builder.add 'todos.state = ?', 'completed' + else + condition_builder.add 'todos.state = ?', 'active' + end + + @title = "Tracks - Next Actions" + @description = "Filter: " + + if params.key?('due') + due_within = params['due'].to_i + due_within_when = @user.time + due_within.days + condition_builder.add('todos.due <= ?', due_within_when) + due_within_date_s = due_within_when.strftime("%Y-%m-%d") + @title << " due today" if (due_within == 0) + @title << " due within a week" if (due_within == 6) + @description << " with a due date #{due_within_date_s} or earlier" + end + + if params.key?('done') + done_in_last = params['done'].to_i + condition_builder.add('todos.completed_at >= ?', @user.time - done_in_last.days) + @title << " actions completed" + @description << " in the last #{done_in_last.to_s} days" + end + + Todo.with_scope :find => {:conditions => condition_builder.to_conditions} do + yield + end + + end + + def with_parent_resource_scope(&block) + if (params[:context_id]) + context = @user.contexts.find_by_params(params) + Todo.with_scope :find => {:conditions => ['todos.context_id = ?', context.id]} do + yield + end + elsif (params[:project_id]) + project = @user.projects.find_by_params(params) + Todo.with_scope :find => {:conditions => ['todos.project_id = ?', project.id]} do + yield + end + else + yield + end + end + + def with_limit_scope(&block) + if params.key?('limit') + Todo.with_scope :find => {:limit => params['limit']} do + yield + end + #@description = limit ? "Lists the last #{limit} incomplete next actions" : "Lists incomplete next actions" + else + yield + end + end + + def init_todos + with_feed_query_scope do + with_parent_resource_scope do + with_limit_scope do + + # Exclude hidden projects from count on home page + @todos = @user.todos.find(:all, :conditions => ['todos.state = ? or todos.state = ?', 'active', 'complete'], :include => [ :project, :context, :tags ]) + + # Exclude hidden projects from the home page + @not_done_todos = @user.todos.find(:all, :conditions => ['todos.state = ?', 'active'], :order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC", :include => [ :project, :context, :tags ]) + + end + end + end end def determine_down_count @@ -323,5 +394,92 @@ class TodosController < ApplicationController end end end - + + def render_todos_html + lambda do + @page_title = "TRACKS::List tasks" + + # If you've set no_completed to zero, the completed items box + # isn't shown on the home page + max_completed = @user.prefs.show_number_completed + @done = @user.completed_todos.find(:all, :limit => max_completed, :include => [ :context, :project, :tags ]) unless max_completed == 0 + + # Set count badge to number of not-done, not hidden context items + @count = @todos.reject { |x| !x.active? || x.context.hide? }.size + + render + end + end + + def render_rss_feed + lambda do + render_rss_feed_for @todos, :feed => Todo.feed_options(@user), + :item => { + :title => :description, + :link => lambda { |t| context_url(t.context) }, + :description => todo_feed_content + } + end + end + + def todo_feed_content + lambda do |i| + item_notes = sanitize(markdown( i.notes )) if i.notes? + due = "
Due: #{format_date(i.due)}
\n" if i.due? + done = "
Completed: #{format_date(i.completed_at)}
\n" if i.completed? + context_link = "#{ i.context.name }" + if i.project_id? + project_link = "#{ i.project.name }" + else + project_link = "none" + end + "#{done||''}#{due||''}#{item_notes||''}\n
Project: #{project_link}
\n
Context: #{context_link}
" + end + end + + def render_atom_feed + lambda do + render_atom_feed_for @todos, :feed => Todo.feed_options(@user), + :item => { + :title => :description, + :link => lambda { |t| context_url(t.context) }, + :description => todo_feed_content, + :author => lambda { |p| nil } + } + end + end + + def render_text_feed + lambda do + render :action => 'index_text', :layout => false, :content_type => Mime::TEXT + end + end + + def render_ical_feed + lambda do + render :action => 'index_ical', :layout => false, :content_type => Mime::ICS + end + end + + def self.is_feed_request(req) + ['rss','atom','txt','ics'].include?(req.parameters[:format]) + end + + class FindConditionBuilder + + def initialize + @queries = Array.new + @params = Array.new + end + + def add(query, param) + @queries << query + @params << param + end + + def to_conditions + [@queries.join(' AND ')] + @params + end + end + end diff --git a/tracks/app/helpers/application_helper.rb b/tracks/app/helpers/application_helper.rb index 826ddf88..ab3a91da 100644 --- a/tracks/app/helpers/application_helper.rb +++ b/tracks/app/helpers/application_helper.rb @@ -1,32 +1,10 @@ # The methods added to this helper will be available to all templates in the application. module ApplicationHelper - - # Convert a date object to the format specified - # in config/settings.yml - # - def format_date(date) - if date - date_format = @user.prefs.date_format - formatted_date = date.strftime("#{date_format}") - else - formatted_date = '' - end - formatted_date - end def user_time @user.time end - - # Uses RedCloth to transform text using either Textile or Markdown - # Need to require redcloth above - # RedCloth 3.0 or greater is needed to use Markdown, otherwise it only handles Textile - # - def markdown(text) - RedCloth.new(text).to_html - end - # Replicates the link_to method but also checks request.request_uri to find # current page. If that matches the url, the link is marked # id = "current" diff --git a/tracks/app/helpers/feed_helper.rb b/tracks/app/helpers/feed_helper.rb deleted file mode 100644 index 18cb2791..00000000 --- a/tracks/app/helpers/feed_helper.rb +++ /dev/null @@ -1,43 +0,0 @@ -module FeedHelper - - # Build a nicely formatted text string for display - # Context forms the heading, then the items are - # indented underneath. If there is a due date - # and the item is in a project, these are also displayed - # - def build_text_page(list,context) - result_string = "" - list.each do |item| - if item.context_id == context.id - result_string << "\n" + context.name.upcase + ":\n" if result_string.empty? - - if (item.completed?) && item.completed_at - result_string << " [Completed: " + format_date(item.completed_at) + "] " - end - - if item.due - result_string << " [Due: " + format_date(item.due) + "] " - result_string << item.description + " " - else - result_string << " " + item.description + " " - end - - if item.project_id - result_string << "(" + item.project.name + ")" - end - result_string << "\n" - end - end - return result_string - end - - def format_ical_notes(notes) - split_notes = notes.split(/\n/) - joined_notes = split_notes.join("\\n") - end - - def format_ical_uid(todo) - sprintf("%s%s%s%s", request.protocol, request.host, request.port_string, todo_url(todo)) - end - -end diff --git a/tracks/app/helpers/feedlist_helper.rb b/tracks/app/helpers/feedlist_helper.rb index ebbfd6b4..562e6521 100644 --- a/tracks/app/helpers/feedlist_helper.rb +++ b/tracks/app/helpers/feedlist_helper.rb @@ -1,24 +1,11 @@ module FeedlistHelper - def rss_feed_link(options = {}) - image_tag = image_tag("feed-icon.png", :size => "16X16", :border => 0, :class => "rss-icon") - linkoptions = {:controller => 'feed', :action => 'rss', :login => "#{@user.login}", :token => "#{@user.word}"} - linkoptions.merge!(options) - link_to(image_tag, linkoptions, :title => "RSS feed") - end - def rss_formatted_link(options = {}) image_tag = image_tag("feed-icon.png", :size => "16X16", :border => 0, :class => "rss-icon") linkoptions = { :token => @user.word, :format => 'rss' } linkoptions.merge!(options) link_to(image_tag, linkoptions, :title => "RSS feed") end - - def text_feed_link(options = {}) - linkoptions = {:controller => 'feed', :action => 'text', :login => "#{@user.login}", :token => "#{@user.word}"} - linkoptions.merge!(options) - link_to('TXT', linkoptions, :title => "Plain text feed" ) - end def text_formatted_link(options = {}) linkoptions = { :token => @user.word, :format => 'txt' } @@ -26,12 +13,10 @@ module FeedlistHelper link_to('TXT', linkoptions, :title => "Plain text feed" ) end - - def ical_feed_link(options = {}) - linkoptions = {:controller => 'feed', :action => 'ical', :login => "#{@user.login}", :token => "#{@user.word}"} + def ical_formatted_link(options = {}) + linkoptions = { :token => @user.word, :format => 'ics' } linkoptions.merge!(options) - link_to('iCal', linkoptions, :title => "iCal feed") + link_to('iCal', linkoptions, :title => "iCal feed" ) end - end diff --git a/tracks/app/helpers/login_helper.rb b/tracks/app/helpers/login_helper.rb index bffb636c..b0ac7165 100644 --- a/tracks/app/helpers/login_helper.rb +++ b/tracks/app/helpers/login_helper.rb @@ -1,18 +1,3 @@ module LoginHelper - - def render_errors(obj) - return "" unless obj - return "" unless request.post? - tag = String.new - - unless obj.valid? - tag << %{} - end - tag - end - - end \ No newline at end of file diff --git a/tracks/app/helpers/todos_helper.rb b/tracks/app/helpers/todos_helper.rb index 17a06855..7c26ed62 100644 --- a/tracks/app/helpers/todos_helper.rb +++ b/tracks/app/helpers/todos_helper.rb @@ -180,6 +180,11 @@ module TodosHelper return array_or_string_for_javascript(['Create a new context']) if @contexts.empty? array_or_string_for_javascript( @contexts.collect{|c| escape_javascript(c.name) } ) end + + def format_ical_notes(notes) + split_notes = notes.split(/\n/) + joined_notes = split_notes.join("\\n") + end private diff --git a/tracks/app/models/context.rb b/tracks/app/models/context.rb index f6b88dc1..b4d29f08 100644 --- a/tracks/app/models/context.rb +++ b/tracks/app/models/context.rb @@ -19,7 +19,7 @@ class Context < ActiveRecord::Base def self.feed_options(user) { :title => 'Tracks Contexts', - :description => "Lists all the contexts for #{user.display_name}." + :description => "Lists all the contexts for #{user.display_name}" } end @@ -37,7 +37,7 @@ class Context < ActiveRecord::Base def summary(undone_todo_count) s = "

#{undone_todo_count}. " - s += "Context is #{hidden? ? 'Hidden' : 'Active'}. " + s += "Context is #{hidden? ? 'Hidden' : 'Active'}." s += "

" s end diff --git a/tracks/app/models/project.rb b/tracks/app/models/project.rb index 84022914..46519b37 100644 --- a/tracks/app/models/project.rb +++ b/tracks/app/models/project.rb @@ -40,50 +40,34 @@ class Project < ActiveRecord::Base def self.feed_options(user) { :title => 'Tracks Projects', - :description => "Lists all the projects for #{user.display_name}." + :description => "Lists all the projects for #{user.display_name}" } end def to_param url_friendly_name end - - def description_present? - attribute_present?("description") - end - - def linkurl_present? - attribute_present?("linkurl") - end - - def title - name - end - - def summary(undone_todo_count) - project_description = '' - project_description += sanitize(markdown( description )) if description_present? - project_description += "

#{undone_todo_count}. " - project_description += "Project is #{state}. " - project_description += "#{linkurl}" if linkurl_present? - project_description += "

" - project_description - end def hide_todos todos.each do |t| - t.hide! unless t.completed? || t.deferred? - t.save + unless t.completed? || t.deferred? + t.hide! + t.save + end end end def unhide_todos todos.each do |t| - t.unhide! if t.project_hidden? - t.save + if t.project_hidden? + t.unhide! + t.save + end end end - + + # would prefer to call this method state=(), but that causes an endless loop + # as a result of acts_as_state_machine calling state=() to update the attribute def transition_to(candidate_state) case candidate_state.to_sym when current_state diff --git a/tracks/app/models/todo.rb b/tracks/app/models/todo.rb index eb87de24..b0080439 100644 --- a/tracks/app/models/todo.rb +++ b/tracks/app/models/todo.rb @@ -1,5 +1,4 @@ class Todo < ActiveRecord::Base - require 'validations' belongs_to :context, :order => 'name' belongs_to :project @@ -45,12 +44,12 @@ class Todo < ActiveRecord::Base validates_presence_of :context def validate - if deferred? && !show_from.blank? && show_from < user.date - errors.add("Show From", "must be a date in the future.") + if !show_from.blank? && show_from < user.date + errors.add("show_from", "must be a date in the future") end end - def toggle_completion + def toggle_completion! if completed? activate! else @@ -78,11 +77,18 @@ class Todo < ActiveRecord::Base alias_method :original_set_initial_state, :set_initial_state def set_initial_state - if show_from && (show_from > Time.now.utc.to_date) + if show_from && (show_from > user.date) write_attribute self.class.state_column, 'deferred' else original_set_initial_state end end + def self.feed_options(user) + { + :title => 'Tracks Actions', + :description => "Actions for #{user.display_name}" + } + end + end \ No newline at end of file diff --git a/tracks/app/models/user.rb b/tracks/app/models/user.rb index b944351b..43dac6f9 100644 --- a/tracks/app/models/user.rb +++ b/tracks/app/models/user.rb @@ -13,6 +13,8 @@ class User < ActiveRecord::Base find_by_url_friendly_name(params['id']) elsif params['context'] find_by_url_friendly_name(params['context']) + elsif params['context_id'] + find_by_url_friendly_name(params['context_id']) end end end @@ -28,6 +30,8 @@ class User < ActiveRecord::Base find_by_url_friendly_name(params['id']) elsif params['project'] find_by_url_friendly_name(params['project']) + elsif params['project_id'] + find_by_url_friendly_name(params['project_id']) end end def update_positions(project_ids) @@ -61,7 +65,7 @@ class User < ActiveRecord::Base :conditions => [ 'state = ?', 'deferred' ], :order => 'show_from ASC, todos.created_at DESC' do def find_and_activate_ready - find(:all, :conditions => ['show_from <= ?', Time.now.utc.to_date ]).collect { |t| t.activate_and_save! } + find(:all, :conditions => ['show_from <= ?', Time.now.utc.to_date.to_time ]).collect { |t| t.activate_and_save! } end end has_many :completed_todos, @@ -90,9 +94,14 @@ class User < ActiveRecord::Base validates_confirmation_of :password validates_length_of :login, :within => 3..80 validates_uniqueness_of :login, :on => :create - validates_inclusion_of :auth_type, :in => Tracks::Config.auth_schemes, :message=>"not a valid authentication type" validates_presence_of :open_id_url, :if => Proc.new{|user| user.auth_type == 'open_id'} + def validate + unless Tracks::Config.auth_schemes.include?(auth_type) + errors.add("auth_type", "not a valid authentication type") + end + end + alias_method :prefs, :preference def self.authenticate(login, pass) diff --git a/tracks/app/views/contexts/_text_context.rhtml b/tracks/app/views/contexts/_text_context.rhtml new file mode 100644 index 00000000..bfc5babb --- /dev/null +++ b/tracks/app/views/contexts/_text_context.rhtml @@ -0,0 +1,8 @@ +<% +context = text_context +todos_in_context = todos.select { |t| t.context_id == context.id } +if todos_in_context.length > 0 + %> +<%= context.name.upcase %>: +<% end -%> +<%= render :partial => "todos/text_todo", :collection => todos_in_context -%> \ No newline at end of file diff --git a/tracks/app/views/feed/rss.rxml b/tracks/app/views/feed/rss.rxml deleted file mode 100644 index 39ce9069..00000000 --- a/tracks/app/views/feed/rss.rxml +++ /dev/null @@ -1,25 +0,0 @@ -xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do - xml.channel do - xml.title(@title) - xml.link("http://#{request.host}:#{request.port}/todos/list") - xml.description(@description) - @todos.each do |i| - xml.item do - xml.title(i.description) - xml.link(context_url(i.context)) - item_notes = sanitize(markdown( i.notes )) if i.notes? - due = "
Due: #{format_date(i.due)}
\n" if i.due? - toggle_link = link_to( "mark as done", {:only_path => false, :controller => "todos", :action => "toggle_check", :id => i.id}) - done = "
#{toggle_link}
" unless i.completed? - done = "
Completed: #{format_date(i.completed_at)}
\n" if i.completed? - context_link = link_to( i.context.name, context_url(i.context) ) - if i.project_id? - project_link = link_to(i.project.name, project_url(i.project) ) - else - project_link = "none" - end - xml.description("#{done||''}#{due||''}#{item_notes||''}\n
Project: #{project_link}
\n
Context: #{context_link}
") - end - end - end -end \ No newline at end of file diff --git a/tracks/app/views/feed/text.rhtml b/tracks/app/views/feed/text.rhtml deleted file mode 100644 index 1efef1bc..00000000 --- a/tracks/app/views/feed/text.rhtml +++ /dev/null @@ -1,3 +0,0 @@ -<% for @context in @contexts -%> - <%= build_text_page( @todos, @context ) -%> -<% end -%> diff --git a/tracks/app/views/feedlist/index.rhtml b/tracks/app/views/feedlist/index.rhtml index 46ea8006..0b37ea82 100644 --- a/tracks/app/views/feedlist/index.rhtml +++ b/tracks/app/views/feedlist/index.rhtml @@ -11,32 +11,32 @@