diff --git a/.gitignore b/.gitignore
index bd1d8742..433e85a0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,3 +9,5 @@ nbproject
vendor/plugins/query_trace/
db/schema.rb
.dotest
+public/javascripts/cache
+public/stylesheets/cache
\ No newline at end of file
diff --git a/README b/README
index 28cf4e46..5cce7ac7 100644
--- a/README
+++ b/README
@@ -8,12 +8,10 @@
* Mailing list: http://lists.rousette.org.uk/mailman/listinfo/tracks-discuss
* Original developer: bsag (http://www.rousette.org.uk/)
* Contributors: http://dev.rousette.org.uk/wiki/Tracks/Contributing/Contributors
-* Version: 1.6
+* Version: 1.7RC
* Copyright: (cc) 2004-2008 rousette.org.uk.
* License: GNU GPL
-**An important note for version 1.6: OpenID support is broken in this release. The fix isn't trivial because of changes to the `ruby-openid` gem, so we wanted to get this version out now and fix OpenID for the next release. If you depend on OpenID integration, we recommend waiting until the next release.**
-
All the documentation for Tracks can be found within the /doc directory. It contains a manual in HTML (manual.html) or PDF format (manual.pdf), and this includes full instructions for both new installations and upgrades from older installations of Tracks. The instructions might appear long and intimidatingly complex, but that is mostly because of the number of different platforms supported, and the different configurations which can be used (e.g. running Tracks on your local computer or on a remote server). If you choose the appropriate section for your situation (installation vs. upgrade), and use the easiest (recommended) method, you should find the instructions easy to follow. If you encounter problems, try searching the wiki, forum or mailing list (URLs above), and ask a question if you cannot find a solution to your problem.
For those upgrading, change notes are available in /doc/CHANGELOG. If you are thinking about contributing towards the development of Tracks, please read /doc/README_DEVELOPERS for general information, or /doc/tracks_api_wrapper.rb for information on Tracks' API.
@@ -21,3 +19,4 @@ For those upgrading, change notes are available in /doc/CHANGELOG. If you are th
While fully usable for everyday use, Tracks is still a work in progress. Make sure that you take sensible precautions and back up all your data frequently, taking particular care when you are upgrading.
Enjoy being productive!
+
diff --git a/app/controllers/application.rb b/app/controllers/application.rb
index b24dfd54..0d54b75f 100644
--- a/app/controllers/application.rb
+++ b/app/controllers/application.rb
@@ -32,13 +32,13 @@ class ApplicationController < ActionController::Base
before_filter :set_time_zone
prepend_before_filter :login_required
prepend_before_filter :enable_mobile_content_negotiation
- after_filter :restore_content_type_for_mobile
after_filter :set_charset
include ActionView::Helpers::TextHelper
include ActionView::Helpers::SanitizeHelper
+ extend ActionView::Helpers::SanitizeHelper::ClassMethods
helper_method :format_date, :markdown
# By default, sets the charset to UTF-8 if it isn't already set
@@ -148,21 +148,15 @@ class ApplicationController < ActionController::Base
# during the processing and then setting it to 'text/html' in an
# 'after_filter' -LKM 2007-04-01
def mobile?
- return params[:format] == 'm' || response.content_type == MOBILE_CONTENT_TYPE
+ return params[:format] == 'm'
end
def enable_mobile_content_negotiation
if mobile?
- request.accepts.unshift(Mime::Type::lookup(MOBILE_CONTENT_TYPE))
+ request.format = :m
end
end
- def restore_content_type_for_mobile
- if mobile?
- response.content_type = 'text/html'
- end
- end
-
def create_todo_from_recurring_todo(rt, date=nil)
# create todo and initialize with data from recurring_todo rt
todo = current_user.todos.build( { :description => rt.description, :notes => rt.notes, :project_id => rt.project_id, :context_id => rt.context_id})
@@ -234,8 +228,13 @@ class ApplicationController < ActionController::Base
end
def init_data_for_sidebar
- @projects = @projects || current_user.projects.find(:all, :include => [:default_context ])
- @contexts = @contexts || current_user.contexts
+ @completed_projects = current_user.projects.completed
+ @hidden_projects = current_user.projects.hidden
+ @active_projects = current_user.projects.active
+
+ @active_contexts = current_user.contexts.active
+ @hidden_contexts = current_user.contexts.hidden
+
init_not_done_counts
if prefs.show_hidden_projects_in_sidebar
init_project_hidden_todo_counts(['project'])
@@ -244,13 +243,13 @@ class ApplicationController < ActionController::Base
def init_not_done_counts(parents = ['project','context'])
parents.each do |parent|
- eval("@#{parent}_not_done_counts = @#{parent}_not_done_counts || Todo.count(:conditions => ['user_id = ? and state = ?', current_user.id, 'active'], :group => :#{parent}_id)")
+ eval("@#{parent}_not_done_counts = @#{parent}_not_done_counts || current_user.todos.active.count(:group => :#{parent}_id)")
end
end
def init_project_hidden_todo_counts(parents = ['project','context'])
parents.each do |parent|
- eval("@#{parent}_project_hidden_todo_counts = @#{parent}_project_hidden_todo_counts || Todo.count(:conditions => ['user_id = ? and (state = ? or state = ?)', current_user.id, 'project_hidden', 'active'], :group => :#{parent}_id)")
+ eval("@#{parent}_project_hidden_todo_counts = @#{parent}_project_hidden_todo_counts || current_user.todos.count(:conditions => ['state = ? or state = ?', 'project_hidden', 'active'], :group => :#{parent}_id)")
end
end
diff --git a/app/controllers/contexts_controller.rb b/app/controllers/contexts_controller.rb
index 34c11d26..348151aa 100644
--- a/app/controllers/contexts_controller.rb
+++ b/app/controllers/contexts_controller.rb
@@ -134,8 +134,8 @@ class ContextsController < ApplicationController
def render_contexts_mobile
lambda do
@page_title = "TRACKS::List Contexts"
- @active_contexts = @contexts.find(:all, { :conditions => ["hide = ?", false]})
- @hidden_contexts = @contexts.find(:all, { :conditions => ["hide = ?", true]})
+ @active_contexts = @contexts.active
+ @hidden_contexts = @contexts.hidden
@down_count = @active_contexts.size + @hidden_contexts.size
cookies[:mobile_url]= {:value => request.request_uri, :secure => TRACKS_COOKIES_SECURE}
render :action => 'index_mobile'
@@ -201,6 +201,9 @@ class ContextsController < ApplicationController
:conditions => ['todos.state = ? AND (todos.project_id IS ? OR projects.state = ?)', 'active', nil, 'active'],
:order => "todos.due IS NULL, todos.due ASC, todos.created_at ASC",
:include => [:project, :tags])
+
+ @projects = current_user.projects
+
@count = @not_done_todos.size
@default_project_context_name_map = build_default_project_context_name_map(@projects).to_json
end
diff --git a/app/controllers/feedlist_controller.rb b/app/controllers/feedlist_controller.rb
index 68c7118c..4c2924e9 100644
--- a/app/controllers/feedlist_controller.rb
+++ b/app/controllers/feedlist_controller.rb
@@ -12,12 +12,12 @@ class FeedlistController < ApplicationController
@contexts = current_user.contexts
end
- @active_projects = @projects.select{ |p| p.active? }
- @hidden_projects = @projects.select{ |p| p.hidden? }
- @completed_projects = @projects.select{ |p| p.completed? }
+ @active_projects = current_user.projects.active
+ @hidden_projects = current_user.projects.hidden
+ @completed_projects = current_user.projects.completed
- @active_contexts = @contexts.select{ |c| !c.hidden? }
- @hidden_contexts = @contexts.select{ |c| c.hidden? }
+ @active_contexts = current_user.contexts.active
+ @hidden_contexts = current_user.contexts.hidden
respond_to do |format|
format.html { render :layout => 'standard' }
diff --git a/app/controllers/integrations_controller.rb b/app/controllers/integrations_controller.rb
index 1b071c1e..26f5f99d 100644
--- a/app/controllers/integrations_controller.rb
+++ b/app/controllers/integrations_controller.rb
@@ -1,5 +1,7 @@
class IntegrationsController < ApplicationController
+ skip_before_filter :login_required, :only => :search_plugin
+
def index
@page_title = 'TRACKS::Integrations'
end
@@ -22,4 +24,12 @@ class IntegrationsController < ApplicationController
context = current_user.contexts.find params[:context_id]
render :partial => 'applescript2', :locals => { :context => context }
end
+
+ def search_plugin
+ @icon_data = [File.open(RAILS_ROOT + '/public/images/done.png').read].
+ pack('m').gsub(/\n/, '')
+
+ render :layout => false
+ end
+
end
diff --git a/app/controllers/login_controller.rb b/app/controllers/login_controller.rb
index a9b7e8be..91cfc261 100644
--- a/app/controllers/login_controller.rb
+++ b/app/controllers/login_controller.rb
@@ -6,114 +6,45 @@ class LoginController < ApplicationController
skip_before_filter :login_required
before_filter :login_optional
before_filter :get_current_user
- open_id_consumer if openid_enabled?
def login
- @page_title = "TRACKS::Login"
- @openid_url = cookies[:openid_url] if openid_enabled?
- case request.method
- when :post
- if @user = User.authenticate(params['user_login'], params['user_password'])
- session['user_id'] = @user.id
- # If checkbox on login page checked, we don't expire the session after 1 hour
- # of inactivity and we remember this user for future browser sessions
- session['noexpiry'] = params['user_noexpiry']
- msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire."
- notify :notice, "Login successful: session #{msg}"
- cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year, :secure => TRACKS_COOKIES_SECURE }
- unless should_expire_sessions?
- @user.remember_me
- cookies[:auth_token] = { :value => @user.remember_token , :expires => @user.remember_token_expires_at, :secure => TRACKS_COOKIES_SECURE }
+ if openid_enabled? && using_open_id?
+ login_openid
+ else
+ @page_title = "TRACKS::Login"
+ case request.method
+ when :post
+ if @user = User.authenticate(params['user_login'], params['user_password'])
+ session['user_id'] = @user.id
+ # If checkbox on login page checked, we don't expire the session after 1 hour
+ # of inactivity and we remember this user for future browser sessions
+ session['noexpiry'] = params['user_noexpiry']
+ msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire."
+ notify :notice, "Login successful: session #{msg}"
+ cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year, :secure => TRACKS_COOKIES_SECURE }
+ unless should_expire_sessions?
+ @user.remember_me
+ cookies[:auth_token] = { :value => @user.remember_token , :expires => @user.remember_token_expires_at, :secure => TRACKS_COOKIES_SECURE }
+ end
+ redirect_back_or_home
+ return
+ else
+ @login = params['user_login']
+ notify :warning, "Login unsuccessful"
end
- redirect_back_or_home
- return
- else
- @login = params['user_login']
- notify :warning, "Login unsuccessful"
- end
- when :get
- if User.no_users_yet?
- redirect_to :controller => 'users', :action => 'new'
- return
- end
- end
- respond_to do |format|
- format.html
- format.m { render :action => 'login_mobile.html.erb', :layout => 'mobile' }
+ when :get
+ if User.no_users_yet?
+ redirect_to :controller => 'users', :action => 'new'
+ return
+ end
+ end
+ respond_to do |format|
+ format.html
+ format.m { render :action => 'login_mobile.html.erb', :layout => 'mobile' }
+ end
end
end
- def begin
- # If the URL was unusable (either because of network conditions,
- # a server error, or that the response returned was not an OpenID
- # identity page), the library will return HTTP_FAILURE or PARSE_ERROR.
- # Let the user know that the URL is unusable.
- case open_id_response.status
- when OpenID::SUCCESS
- session['openid_url'] = params[:openid_url]
- session['user_noexpiry'] = params[:user_noexpiry]
- # The URL was a valid identity URL. Now we just need to send a redirect
- # to the server using the redirect_url the library created for us.
-
- # redirect to the server
- respond_to do |format|
- format.html { redirect_to open_id_response.redirect_url((request.protocol + request.host_with_port + "/"), open_id_complete_url) }
- format.m { redirect_to open_id_response.redirect_url((request.protocol + request.host_with_port + "/"), formatted_open_id_complete_url(:format => 'm')) }
- end
- else
- notify :warning, "Unable to find openid server for #{openid_url}
"
- redirect_to_login
- end
- end
-
- def complete
- openid_url = session['openid_url']
- if openid_url.blank?
- notify :error, "expected an openid_url"
- end
-
- case open_id_response.status
- when OpenID::FAILURE
- # In the case of failure, if info is non-nil, it is the
- # URL that we were verifying. We include it in the error
- # message to help the user figure out what happened.
- if open_id_response.identity_url
- msg = "Verification of #{openid_url}(#{open_id_response.identity_url}) failed. "
- else
- msg = "Verification failed. "
- end
- notify :error, open_id_response.msg.to_s + msg
-
- when OpenID::SUCCESS
- # Success means that the transaction completed without
- # error. If info is nil, it means that the user cancelled
- # the verification.
- @user = User.find_by_open_id_url(openid_url)
- unless (@user.nil?)
- session['user_id'] = @user.id
- session['noexpiry'] = session['user_noexpiry']
- msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire."
- notify :notice, "You have successfully verified #{openid_url} as your identity. Login successful: session #{msg}"
- cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year, :secure => TRACKS_COOKIES_SECURE }
- unless should_expire_sessions?
- @user.remember_me
- cookies[:auth_token] = { :value => @user.remember_token , :expires => @user.remember_token_expires_at, :secure => TRACKS_COOKIES_SECURE }
- end
- cookies[:openid_url] = { :value => openid_url, :expires => Time.now + 1.year, :secure => TRACKS_COOKIES_SECURE }
- redirect_back_or_home
- else
- notify :warning, "You have successfully verified #{openid_url} as your identity, but you do not have a Tracks account. Please ask your administrator to sign you up."
- end
-
- when OpenID::CANCEL
- notify :warning, "Verification cancelled."
-
- else
- notify :warning, "Unknown response status: #{open_id_response.status}"
- end
- redirect_to_login unless performed?
- end
-
def logout
@user.forget_me if logged_in?
cookies.delete :auth_token
@@ -156,5 +87,31 @@ class LoginController < ApplicationController
def should_expire_sessions?
session['noexpiry'] != "on"
end
-
+
+ protected
+
+ def login_openid
+ # If checkbox on login page checked, we don't expire the session after 1 hour
+ # of inactivity and we remember this user for future browser sessions
+ session['noexpiry'] ||= params['user_noexpiry']
+ authenticate_with_open_id do |result, identity_url|
+ if result.successful?
+ if @user = User.find_by_open_id_url(identity_url)
+ session['user_id'] = @user.id
+ msg = (should_expire_sessions?) ? "will expire after 1 hour of inactivity." : "will not expire."
+ notify :notice, "Login successful: session #{msg}"
+ cookies[:tracks_login] = { :value => @user.login, :expires => Time.now + 1.year, :secure => TRACKS_COOKIES_SECURE }
+ unless should_expire_sessions?
+ @user.remember_me
+ cookies[:auth_token] = { :value => @user.remember_token , :expires => @user.remember_token_expires_at, :secure => TRACKS_COOKIES_SECURE }
+ end
+ redirect_back_or_home
+ else
+ notify :warning, "Sorry, no user by that identity URL exists (#{identity_url})"
+ end
+ else
+ notify :warning, result.message
+ end
+ end
+ end
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index b2489c7d..9443168f 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -31,7 +31,7 @@ class ProjectsController < ApplicationController
end
def projects_and_actions
- @projects = @projects.select { |p| p.active? }
+ @projects = @projects.active
respond_to do |format|
format.text {
render :action => 'index_text_projects_and_actions', :layout => false, :content_type => Mime::TEXT
@@ -83,7 +83,7 @@ class ProjectsController < ApplicationController
@go_to_project = params['go_to_project']
@saved = @project.save
@project_not_done_counts = { @project.id => 0 }
- @active_projects_count = current_user.projects.count(:conditions => "state = 'active'")
+ @active_projects_count = current_user.projects.active.count
@contexts = current_user.contexts
respond_to do |format|
format.js { @down_count = current_user.projects.size }
@@ -124,9 +124,9 @@ class ProjectsController < ApplicationController
@project_not_done_counts[@project.id] = @project.reload().not_done_todo_count(:include_project_hidden_todos => true)
end
@contexts = current_user.contexts
- @active_projects_count = current_user.projects.count(:conditions => "state = 'active'")
- @hidden_projects_count = current_user.projects.count(:conditions => "state = 'hidden'")
- @completed_projects_count = current_user.projects.count(:conditions => "state = 'completed'")
+ @active_projects_count = current_user.projects.active.count
+ @hidden_projects_count = current_user.projects.hidden.count
+ @completed_projects_count = current_user.projects.completed.count
render :template => 'projects/update.js.rjs'
return
elsif boolean_param('update_status')
@@ -161,9 +161,9 @@ class ProjectsController < ApplicationController
def destroy
@project.destroy
- @active_projects_count = current_user.projects.count(:conditions => "state = 'active'")
- @hidden_projects_count = current_user.projects.count(:conditions => "state = 'hidden'")
- @completed_projects_count = current_user.projects.count(:conditions => "state = 'completed'")
+ @active_projects_count = current_user.projects.active.count
+ @hidden_projects_count = current_user.projects.hidden.count
+ @completed_projects_count = current_user.projects.completed.count
respond_to do |format|
format.js { @down_count = current_user.projects.size }
format.xml { render :text => "Deleted project #{@project.name}" }
@@ -199,9 +199,9 @@ class ProjectsController < ApplicationController
lambda do
@page_title = "TRACKS::List Projects"
@count = current_user.projects.size
- @active_projects = @projects.select{ |p| p.active? }
- @hidden_projects = @projects.select{ |p| p.hidden? }
- @completed_projects = @projects.select{ |p| p.completed? }
+ @active_projects = @projects.active
+ @hidden_projects = @projects.hidden
+ @completed_projects = @projects.completed
@no_projects = @projects.empty?
@projects.cache_note_counts
@new_project = current_user.projects.build
@@ -211,9 +211,9 @@ class ProjectsController < ApplicationController
def render_projects_mobile
lambda do
- @active_projects = @projects.select{ |p| p.active? }
- @hidden_projects = @projects.select{ |p| p.hidden? }
- @completed_projects = @projects.select{ |p| p.completed? }
+ @active_projects = @projects.active
+ @hidden_projects = @projects.hidden
+ @completed_projects = @projects.completed
@down_count = @active_projects.size + @hidden_projects.size + @completed_projects.size
cookies[:mobile_url]= {:value => request.request_uri, :secure => TRACKS_COOKIES_SECURE}
render :action => 'index_mobile'
diff --git a/app/controllers/recurring_todos_controller.rb b/app/controllers/recurring_todos_controller.rb
index 9928a4d5..668e6acb 100644
--- a/app/controllers/recurring_todos_controller.rb
+++ b/app/controllers/recurring_todos_controller.rb
@@ -118,7 +118,7 @@ class RecurringTodosController < ApplicationController
else
@message += " / did not create todo"
end
- @count = current_user.recurring_todos.count(:all, :conditions => ["state = ?", "active"])
+ @count = current_user.recurring_todos.active.count
else
@message = "Error saving recurring todo"
end
@@ -140,7 +140,7 @@ class RecurringTodosController < ApplicationController
# delete the recurring todo
@saved = @recurring_todo.destroy
- @remaining = current_user.recurring_todos.count(:all)
+ @remaining = current_user.recurring_todos.count
respond_to do |format|
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index baaa25dd..93bdb23e 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -1,27 +1,30 @@
-class SearchController < ApplicationController
-
- helper :todos, :application, :notes, :projects
-
- def results
- @source_view = params['_source_view'] || 'search'
- @page_title = "TRACKS::Search Results for #{params[:search]}"
- terms = '%' + params[:search] + '%'
- @found_todos = current_user.todos.find(:all, :conditions => ["todos.description LIKE ? OR todos.notes LIKE ?", terms, terms], :include => [:tags, :project, :context])
- @found_projects = current_user.projects.find(:all, :conditions => ["name LIKE ? or description LIKE ?", terms, terms])
- @found_notes = current_user.notes.find(:all, :conditions => ["body LIKE ?", terms])
-
- @count = @found_todos.size + @found_projects.size + @found_notes.size
-
- init_not_done_counts(['project'])
- init_project_hidden_todo_counts(['project'])
- end
-
- def index
- @page_title = "TRACKS::Search"
- end
-
- def init
- @source_view = params['_source_view'] || 'search'
- end
-
-end
+class SearchController < ApplicationController
+
+ helper :todos, :application, :notes, :projects
+
+ def results
+ @source_view = params['_source_view'] || 'search'
+ @page_title = "TRACKS::Search Results for #{params[:search]}"
+ terms = '%' + params[:search] + '%'
+ @found_todos = current_user.todos.find(:all, :conditions => ["todos.description LIKE ? OR todos.notes LIKE ?", terms, terms], :include => [:tags, :project, :context])
+ @found_projects = current_user.projects.find(:all, :conditions => ["name LIKE ? OR description LIKE ?", terms, terms])
+ @found_notes = current_user.notes.find(:all, :conditions => ["body LIKE ?", terms])
+ @found_contexts = current_user.contexts.find(:all, :conditions => ["name LIKE ?", terms])
+ # TODO: limit search to tags on todos
+ @found_tags = current_user.tags.find(:all, :conditions => ["name LIKE ?", terms])
+
+ @count = @found_todos.size + @found_projects.size + @found_notes.size + @found_contexts.size + @found_tags.size
+
+ init_not_done_counts
+ init_project_hidden_todo_counts
+ end
+
+ def index
+ @page_title = "TRACKS::Search"
+ end
+
+ def init
+ @source_view = params['_source_view'] || 'search'
+ end
+
+end
diff --git a/app/controllers/stats_controller.rb b/app/controllers/stats_controller.rb
index c74811d4..2d0f95c6 100755
--- a/app/controllers/stats_controller.rb
+++ b/app/controllers/stats_controller.rb
@@ -8,7 +8,7 @@ class StatsController < ApplicationController
@page_title = 'TRACKS::Statistics'
@unique_tags = @tags.count(:all, {:group=>"tag_id"})
- @hidden_contexts = @contexts.find(:all, {:conditions => ["hide = ? ", true]})
+ @hidden_contexts = @contexts.hidden
@first_action = @actions.find(:first, :order => "created_at ASC")
get_stats_actions
diff --git a/app/controllers/todos_controller.rb b/app/controllers/todos_controller.rb
index ad3a762a..8ccf710a 100644
--- a/app/controllers/todos_controller.rb
+++ b/app/controllers/todos_controller.rb
@@ -14,7 +14,7 @@ class TodosController < ApplicationController
@projects = current_user.projects.find(:all, :include => [:default_context])
@contexts = current_user.contexts.find(:all)
- @contexts_to_show = @contexts.reject {|x| x.hide? }
+ @contexts_to_show = current_user.contexts.active
respond_to do |format|
format.html &render_todos_html
@@ -28,7 +28,7 @@ class TodosController < ApplicationController
end
def new
- @projects = current_user.projects.select { |p| p.active? }
+ @projects = current_user.projects.active
@contexts = current_user.contexts.find(:all)
respond_to do |format|
format.m {
@@ -76,7 +76,7 @@ class TodosController < ApplicationController
format.m do
@return_path=cookies[:mobile_url]
# todo: use function for this fixed path
- @return_path='/mobile' if @return_path.nil?
+ @return_path='/m' if @return_path.nil?
if @saved
redirect_to @return_path
else
@@ -116,7 +116,7 @@ class TodosController < ApplicationController
def show
respond_to do |format|
format.m do
- @projects = current_user.projects.select { |p| p.active? }
+ @projects = current_user.projects.active
@contexts = current_user.contexts.find(:all)
@edit_mobile = true
@return_path=cookies[:mobile_url]
@@ -399,8 +399,9 @@ class TodosController < ApplicationController
:limit => max_completed,
:conditions => ['taggings.user_id = ? and state = ?', current_user.id, 'completed'],
:order => 'todos.completed_at DESC')
-
- @contexts = current_user.contexts.find(:all)
+
+ @projects = current_user.projects
+ @contexts = current_user.contexts
@contexts_to_show = @contexts.reject {|x| x.hide? }
# Set count badge to number of items with this tag
@@ -442,33 +443,33 @@ class TodosController < ApplicationController
due_next_week_date = due_this_week_date + 7.days
due_this_month_date = Time.zone.now.end_of_month
- @due_today = current_user.todos.find(:all,
+ @due_today = current_user.todos.not_completed.find(:all,
:include => [:taggings, :tags],
- :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due <= ?', 'active', 'deferred', due_today_date],
+ :conditions => ['todos.due <= ?', due_today_date],
:order => "due")
- @due_this_week = current_user.todos.find(:all,
+ @due_this_week = current_user.todos.not_completed.find(:all,
:include => [:taggings, :tags],
- :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ? AND todos.due <= ?', 'active', 'deferred', due_today_date, due_this_week_date],
+ :conditions => ['todos.due > ? AND todos.due <= ?', due_today_date, due_this_week_date],
:order => "due")
- @due_next_week = current_user.todos.find(:all,
+ @due_next_week = current_user.todos.not_completed.find(:all,
:include => [:taggings, :tags],
- :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ? AND todos.due <= ?', 'active', 'deferred', due_this_week_date, due_next_week_date],
+ :conditions => ['todos.due > ? AND todos.due <= ?', due_this_week_date, due_next_week_date],
:order => "due")
- @due_this_month = current_user.todos.find(:all,
+ @due_this_month = current_user.todos.not_completed.find(:all,
:include => [:taggings, :tags],
- :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ? AND todos.due <= ?', 'active', 'deferred', due_next_week_date, due_this_month_date],
+ :conditions => ['todos.due > ? AND todos.due <= ?', due_next_week_date, due_this_month_date],
:order => "due")
- @due_after_this_month = current_user.todos.find(:all,
+ @due_after_this_month = current_user.todos.not_completed.find(:all,
:include => [:taggings, :tags],
- :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ?', 'active', 'deferred', due_this_month_date],
+ :conditions => ['todos.due > ?', due_this_month_date],
:order => "due")
-
+
+ @count = current_user.todos.not_completed.are_due.count
+
respond_to do |format|
format.html
format.ics {
- @due_all = current_user.todos.find(:all,
- :conditions => ['(todos.state = ? OR todos.state = ?) AND NOT todos.due IS NULL', 'active', 'deferred'],
- :order => "due")
+ @due_all = current_user.todos.not_completed.are_due.find(:all, :order => "due")
render :action => 'calendar', :layout => false, :content_type => Mime::ICS
}
end
@@ -536,13 +537,17 @@ class TodosController < ApplicationController
end
def with_parent_resource_scope(&block)
+ @feed_title = "Actions "
if (params[:context_id])
@context = current_user.contexts.find_by_params(params)
+ @feed_title = @feed_title + "in context '#{@context.name}'"
Todo.send :with_scope, :find => {:conditions => ['todos.context_id = ?', @context.id]} do
yield
end
elsif (params[:project_id])
@project = current_user.projects.find_by_params(params)
+ @feed_title = @feed_title + "in project '#{@project.name}'"
+ @project_feed = true
Todo.send :with_scope, :find => {:conditions => ['todos.project_id = ?', @project.id]} do
yield
end
@@ -718,7 +723,7 @@ class TodosController < ApplicationController
render_rss_feed_for @todos, :feed => todo_feed_options,
:item => {
:title => :description,
- :link => lambda { |t| context_url(t.context) },
+ :link => lambda { |t| @project_feed.nil? ? context_url(t.context) : project_url(t.project) },
:guid => lambda { |t| todo_url(t) },
:description => todo_feed_content
}
@@ -726,7 +731,9 @@ class TodosController < ApplicationController
end
def todo_feed_options
- Todo.feed_options(current_user)
+ options = Todo.feed_options(current_user)
+ options[:title] = @feed_title
+ return options
end
def todo_feed_content
@@ -779,8 +786,8 @@ class TodosController < ApplicationController
if todo.from_recurring_todo?
recurring_todo = todo.recurring_todo
- # check if there are active todos belonging to this recurring todo.
- # only add new one if all active todos are completed
+ # check if there are active todos belonging to this recurring todo. only
+ # add new one if all active todos are completed
if recurring_todo.todos.active.count == 0
# check for next todo either from the due date or the show_from date
@@ -788,7 +795,7 @@ class TodosController < ApplicationController
# if both due and show_from are nil, check for a next todo from now
date_to_check = Time.zone.now if date_to_check.nil?
-
+
if recurring_todo.active? && recurring_todo.has_next_todo(date_to_check)
# shift the reference date to yesterday if date_to_check is furher in
@@ -799,7 +806,7 @@ class TodosController < ApplicationController
# that new todos due for today will be created instead of new todos
# for tomorrow.
date = date_to_check.at_midnight >= Time.zone.now.at_midnight ? date_to_check : Time.zone.now-1.day
-
+
new_recurring_todo = create_todo_from_recurring_todo(recurring_todo, date)
end
end
@@ -834,20 +841,20 @@ class TodosController < ApplicationController
due_this_month_date = Time.zone.now.end_of_month
case id
when "due_today"
- return 0 == current_user.todos.count(:all,
- :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due <= ?', 'active', 'deferred', due_today_date])
+ return 0 == current_user.todos.not_completed.count(:all,
+ :conditions => ['todos.due <= ?', due_today_date])
when "due_this_week"
- return 0 == current_user.todos.count(:all,
- :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ? AND todos.due <= ?', 'active', 'deferred', due_today_date, due_this_week_date])
+ return 0 == current_user.todos.not_completed.count(:all,
+ :conditions => ['todos.due > ? AND todos.due <= ?', due_today_date, due_this_week_date])
when "due_next_week"
- return 0 == current_user.todos.count(:all,
- :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ? AND todos.due <= ?', 'active', 'deferred', due_this_week_date, due_next_week_date])
+ return 0 == current_user.todos.not_completed.count(:all,
+ :conditions => ['todos.due > ? AND todos.due <= ?', due_this_week_date, due_next_week_date])
when "due_this_month"
- return 0 == current_user.todos.count(:all,
- :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ? AND todos.due <= ?', 'active', 'deferred', due_next_week_date, due_this_month_date])
+ return 0 == current_user.todos.not_completed.count(:all,
+ :conditions => ['todos.due > ? AND todos.due <= ?', due_next_week_date, due_this_month_date])
when "due_after_this_month"
- return 0 == current_user.todos.count(:all,
- :conditions => ['(todos.state = ? OR todos.state = ?) AND todos.due > ?', 'active', 'deferred', due_this_month_date])
+ return 0 == current_user.todos.not_completed.count(:all,
+ :conditions => ['todos.due > ?', due_this_month_date])
else
raise Exception.new, "unknown due id for calendar: '#{id}'"
end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 860f31cc..98f45cb9 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -1,10 +1,4 @@
class UsersController < ApplicationController
-
- if openid_enabled?
- open_id_consumer
- before_filter :begin_open_id_auth, :only => :update_auth_type
- end
-
before_filter :admin_login_required, :only => [ :index, :show, :destroy ]
skip_before_filter :login_required, :only => [ :new, :create ]
prepend_before_filter :login_optional, :only => [ :new, :create ]
@@ -153,18 +147,25 @@ class UsersController < ApplicationController
end
def update_auth_type
- if (params[:user][:auth_type] == 'open_id') && openid_enabled?
- case open_id_response.status
- when OpenID::SUCCESS
- # The URL was a valid identity URL. Now we just need to send a redirect
- # to the server using the redirect_url the library created for us.
- session['openid_url'] = params[:openid_url]
-
- # redirect to the server
- redirect_to open_id_response.redirect_url((request.protocol + request.host_with_port + "/"), url_for(:action => 'complete'))
+ if (params[:open_id_complete] || (params[:user][:auth_type] == 'open_id')) && openid_enabled?
+ authenticate_with_open_id do |result, identity_url|
+ if result.successful?
+ # Success means that the transaction completed without
+ # error. If info is nil, it means that the user cancelled
+ # the verification.
+ @user.auth_type = 'open_id'
+ @user.open_id_url = identity_url
+ if @user.save
+ notify :notice, "You have successfully verified #{identity_url} as your identity and set your authentication type to Open ID."
+ else
+ debugger
+ notify :warning, "You have successfully verified #{identity_url} as your identity but there was a problem saving your authentication preferences."
+ end
+ redirect_to preferences_path
else
- notify :warning, "Unable to find openid server for #{openid_url}
"
+ notify :warning, result.message
redirect_to :action => 'change_auth_type'
+ end
end
return
end
@@ -178,47 +179,6 @@ class UsersController < ApplicationController
end
end
- def complete
- return unless openid_enabled?
- openid_url = session['openid_url']
- if openid_url.blank?
- notify :error, "expected an openid_url"
- end
- case open_id_response.status
- when OpenID::FAILURE
- # In the case of failure, if info is non-nil, it is the
- # URL that we were verifying. We include it in the error
- # message to help the user figure out what happened.
- if open_id_response.identity_url
- msg = "Verification of #{openid_url}(#{open_id_response.identity_url}) failed. "
- else
- msg = "Verification failed. "
- end
- notify :error, open_id_response.msg.to_s + msg
-
- when OpenID::SUCCESS
- # Success means that the transaction completed without
- # error. If info is nil, it means that the user cancelled
- # the verification.
- @user.auth_type = 'open_id'
- @user.open_id_url = openid_url
- if @user.save
- notify :notice, "You have successfully verified #{openid_url} as your identity and set your authentication type to Open ID."
- else
- notify :warning, "You have successfully verified #{openid_url} as your identity but there was a problem saving your authentication preferences."
- end
- redirect_to preferences_path
-
- when OpenID::CANCEL
- notify :warning, "Verification cancelled."
-
- else
- notify :warning, "Unknown response status: #{open_id_response.status}"
- end
- redirect_to :action => 'change_auth_type' unless performed?
- end
-
-
def refresh_token
@user.generate_token
@user.save!
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index a4147313..549f2fbc 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -8,7 +8,7 @@ module ApplicationHelper
# 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"
- #
+ #
def navigation_link(name, options = {}, html_options = nil, *parameters_for_method_reference)
if html_options
html_options = html_options.stringify_keys
@@ -29,7 +29,7 @@ module ApplicationHelper
# Check due date in comparison to today's date Flag up date appropriately with
# a 'traffic light' colour code
- #
+ #
def due_date(due)
if due == nil
return ""
@@ -62,7 +62,7 @@ module ApplicationHelper
# Check due date in comparison to today's date Flag up date appropriately with
# a 'traffic light' colour code Modified method for mobile screen
- #
+ #
def due_date_mobile(due)
if due == nil
return ""
@@ -92,7 +92,7 @@ module ApplicationHelper
# Returns a count of next actions in the given context or project. The result
# is count and a string descriptor, correctly pluralised if there are no
# actions or multiple actions
- #
+ #
def count_undone_todos_phrase(todos_parent, string="actions")
@controller.count_undone_todos_phrase(todos_parent, string)
end
@@ -143,5 +143,31 @@ module ApplicationHelper
page.replace 'flash', "