Merge branch 'master' of git://github.com/bsag/tracks

This commit is contained in:
Reinier Balt 2009-02-15 22:10:02 +01:00
commit 765d3440d7
22 changed files with 765 additions and 715 deletions

2
README
View file

@ -8,7 +8,7 @@
* Mailing list: http://lists.rousette.org.uk/mailman/listinfo/tracks-discuss * Mailing list: http://lists.rousette.org.uk/mailman/listinfo/tracks-discuss
* Original developer: bsag (http://www.rousette.org.uk/) * Original developer: bsag (http://www.rousette.org.uk/)
* Contributors: http://getontracks.org/wiki/Tracks/Contributing/Contributors * Contributors: http://getontracks.org/wiki/Tracks/Contributing/Contributors
* Version: 1.7 * Version: 1.7RC2
* Copyright: (cc) 2004-2008 rousette.org.uk. * Copyright: (cc) 2004-2008 rousette.org.uk.
* License: GNU GPL * License: GNU GPL

View file

@ -34,8 +34,6 @@ class ApplicationController < ActionController::Base
prepend_before_filter :enable_mobile_content_negotiation prepend_before_filter :enable_mobile_content_negotiation
after_filter :set_charset after_filter :set_charset
include ActionView::Helpers::TextHelper include ActionView::Helpers::TextHelper
include ActionView::Helpers::SanitizeHelper include ActionView::Helpers::SanitizeHelper
extend ActionView::Helpers::SanitizeHelper::ClassMethods extend ActionView::Helpers::SanitizeHelper::ClassMethods

View file

@ -21,8 +21,22 @@ class DataController < ApplicationController
all_tables['todos'] = current_user.todos.find(:all) all_tables['todos'] = current_user.todos.find(:all)
all_tables['contexts'] = current_user.contexts.find(:all) all_tables['contexts'] = current_user.contexts.find(:all)
all_tables['projects'] = current_user.projects.find(:all) all_tables['projects'] = current_user.projects.find(:all)
all_tables['tags'] = current_user.tags.find(:all)
all_tables['taggings'] = current_user.taggings.find(:all) tags = Tag.find_by_sql([
"SELECT tags.* "+
"FROM tags, taggings, todos "+
"WHERE todos.user_id=? "+
"AND tags.id = taggings.tag_id " +
"AND taggings.taggable_id = todos.id ", current_user.id])
all_tables['tags'] = tags
taggings = Tagging.find_by_sql([
"SELECT taggings.* "+
"FROM taggings, todos "+
"WHERE todos.user_id=? "+
"AND taggings.taggable_id = todos.id ", current_user.id])
all_tables['taggings'] = taggings
all_tables['notes'] = current_user.notes.find(:all) all_tables['notes'] = current_user.notes.find(:all)
all_tables['recurring_todos'] = current_user.recurring_todos.find(:all) all_tables['recurring_todos'] = current_user.recurring_todos.find(:all)

View file

@ -175,7 +175,7 @@ class ProjectsController < ApplicationController
def order def order
project_ids = params["list-active-projects"] || params["list-hidden-projects"] || params["list-completed-projects"] project_ids = params["list-active-projects"] || params["list-hidden-projects"] || params["list-completed-projects"]
projects = current_user.projects.update_positions( project_ids ) @projects = current_user.projects.update_positions( project_ids )
render :nothing => true render :nothing => true
rescue rescue
notify :error, $! notify :error, $!

View file

@ -30,6 +30,7 @@ class RecurringTodosController < ApplicationController
end end
def update def update
# TODO: write tests for updating
@recurring_todo.tag_with(params[:tag_list]) if params[:tag_list] @recurring_todo.tag_with(params[:tag_list]) if params[:tag_list]
@original_item_context_id = @recurring_todo.context_id @original_item_context_id = @recurring_todo.context_id
@original_item_project_id = @recurring_todo.project_id @original_item_project_id = @recurring_todo.project_id
@ -69,13 +70,11 @@ class RecurringTodosController < ApplicationController
params["recurring_todo"]["context_id"] = context.id params["recurring_todo"]["context_id"] = context.id
end end
params["recurring_todo"]["weekly_return_monday"]=' ' if params["recurring_todo"]["weekly_return_monday"].nil? # make sure that we set weekly_return_xxx to empty (space) when they are
params["recurring_todo"]["weekly_return_tuesday"]=' ' if params["recurring_todo"]["weekly_return_tuesday"].nil? # not checked (and thus not present in params["recurring_todo"])
params["recurring_todo"]["weekly_return_wednesday"]=' ' if params["recurring_todo"]["weekly_return_wednesday"].nil? %w{monday tuesday wednesday thursday friday saturday sunday}.each do |day|
params["recurring_todo"]["weekly_return_thursday"]=' ' if params["recurring_todo"]["weekly_return_thursday"].nil? params["recurring_todo"]["weekly_return_"+day]=' ' if params["recurring_todo"]["weekly_return_"+day].nil?
params["recurring_todo"]["weekly_return_friday"]=' ' if params["recurring_todo"]["weekly_return_friday"].nil? end
params["recurring_todo"]["weekly_return_saturday"]=' ' if params["recurring_todo"]["weekly_return_saturday"].nil?
params["recurring_todo"]["weekly_return_sunday"]=' ' if params["recurring_todo"]["weekly_return_sunday"].nil?
@saved = @recurring_todo.update_attributes params["recurring_todo"] @saved = @recurring_todo.update_attributes params["recurring_todo"]

View file

@ -6,8 +6,8 @@ class Todo < ActiveRecord::Base
belongs_to :recurring_todo belongs_to :recurring_todo
named_scope :active, :conditions => { :state => 'active' } named_scope :active, :conditions => { :state => 'active' }
named_scope :not_completed, :conditions => ['NOT state = ? ', 'completed'] named_scope :not_completed, :conditions => ['NOT (state = ? )', 'completed']
named_scope :are_due, :conditions => ['NOT todos.due IS NULL'] named_scope :are_due, :conditions => ['NOT (todos.due IS NULL)']
STARRED_TAG_NAME = "starred" STARRED_TAG_NAME = "starred"

View file

@ -59,7 +59,7 @@ class User < ActiveRecord::Base
"SELECT project.id, count(todo.id) as p_count " + "SELECT project.id, count(todo.id) as p_count " +
"FROM projects as project " + "FROM projects as project " +
"LEFT OUTER JOIN todos as todo ON todo.project_id = project.id "+ "LEFT OUTER JOIN todos as todo ON todo.project_id = project.id "+
"WHERE project.user_id = ? AND NOT todo.state='completed' " + "WHERE project.user_id = ? AND NOT (todo.state='completed') " +
query_state + query_state +
" GROUP BY project.id ORDER by p_count DESC",user_id]) " GROUP BY project.id ORDER by p_count DESC",user_id])
self.update_positions(projects.map{ |p| p.id }) self.update_positions(projects.map{ |p| p.id })
@ -91,7 +91,7 @@ class User < ActiveRecord::Base
end end
has_many :completed_todos, has_many :completed_todos,
:class_name => 'Todo', :class_name => 'Todo',
:conditions => ['todos.state = ? and todos.completed_at is not null', 'completed'], :conditions => ['todos.state = ? AND NOT(todos.completed_at IS NULL)', 'completed'],
:order => 'todos.completed_at DESC', :order => 'todos.completed_at DESC',
:include => [ :project, :context ] do :include => [ :project, :context ] do
def completed_within( date ) def completed_within( date )

View file

@ -2,7 +2,7 @@ class AddUpdatedAtToTodos < ActiveRecord::Migration
def self.up def self.up
add_column :todos, :updated_at, :timestamp add_column :todos, :updated_at, :timestamp
execute 'update todos set updated_at = created_at where completed_at IS NULL' execute 'update todos set updated_at = created_at where completed_at IS NULL'
execute 'update todos set updated_at = completed_at where NOT completed_at IS NULL' execute 'update todos set updated_at = completed_at where NOT (completed_at IS NULL)'
end end
def self.down def self.down
remove_column :todos, :updated_at remove_column :todos, :updated_at

Binary file not shown.

Binary file not shown.

View file

@ -6,8 +6,6 @@
body { body {
background: #fff; background: #fff;
color: #000; color: #000;
/* width: 2.5in;
height: 4.7in;*/
font-size: 8.2pt; font-size: 8.2pt;
font-family: "Lucida Grande", "Bitstream Vera Sans", Helvetica, Verdana, Arial, sans-serif; font-family: "Lucida Grande", "Bitstream Vera Sans", Helvetica, Verdana, Arial, sans-serif;
} }
@ -18,7 +16,7 @@ img {
border:0; border:0;
} }
#navcontainer, #input_box, #footer, .big-box, .refresh, .badge, h1, .icon, #minilinks { #navcontainer, #input_box, #footer, .big-box, .refresh, .badge, h1, .icon, #minilinks, .defer-container {
display:none; display:none;
} }

View file

@ -76,31 +76,31 @@ h3 {
/* Rules for the icon links */ /* Rules for the icon links */
img.edit_item {background-image: url(../images/edit_off.png); background-repeat: no-repeat; border: none;} img.edit_item {background-image: url(/images/edit_off.png); background-repeat: no-repeat; border: none;}
a:hover img.edit_item {background-image: url(../images/edit_on.png); background-color: transparent; background-repeat: no-repeat; border: none;} a:hover img.edit_item {background-image: url(/images/edit_on.png); background-color: transparent; background-repeat: no-repeat; border: none;}
img.delete_item {background-image: url(../images/delete_off.png); background-repeat: no-repeat; border: none;} img.delete_item {background-image: url(/images/delete_off.png); background-repeat: no-repeat; border: none;}
a:hover img.delete_item {background-image: url(../images/delete_on.png);background-color: transparent;background-repeat: no-repeat; border: none;} a:hover img.delete_item {background-image: url(/images/delete_on.png);background-color: transparent;background-repeat: no-repeat; border: none;}
img.starred_todo {background-image: url(../images/staricons.png); background-repeat: no-repeat; border:none; background-position: 0px 0px;} img.starred_todo {background-image: url(/images/staricons.png); background-repeat: no-repeat; border:none; background-position: 0px 0px;}
a:hover img.starred_todo {background-image: url(../images/staricons.png); background-repeat: no-repeat; border:none; background-position: -16px 0px;} a:hover img.starred_todo {background-image: url(/images/staricons.png); background-repeat: no-repeat; border:none; background-position: -16px 0px;}
img.unstarred_todo {background-image: url(../images/staricons.png); background-repeat: no-repeat; border:none; background-position: -32px 0px;} img.unstarred_todo {background-image: url(/images/staricons.png); background-repeat: no-repeat; border:none; background-position: -32px 0px;}
a:hover img.unstarred_todo {background-image: url(../images/staricons.png); background-repeat: no-repeat; border:none; background-position: -48px 0px;} a:hover img.unstarred_todo {background-image: url(/images/staricons.png); background-repeat: no-repeat; border:none; background-position: -48px 0px;}
a.to_top {background: transparent url(../images/top_off.png) no-repeat;} a.to_top {background: transparent url(/images/top_off.png) no-repeat;}
a.to_top:hover {background: transparent url(../images/top_on.png) no-repeat;} a.to_top:hover {background: transparent url(/images/top_on.png) no-repeat;}
a.up {background: transparent url(../images/up_off.png) no-repeat;} a.up {background: transparent url(/images/up_off.png) no-repeat;}
a.up:hover {background: transparent url(../images/up_on.png) no-repeat;} a.up:hover {background: transparent url(/images/up_on.png) no-repeat;}
a.down {background: transparent url(../images/down_off.png) no-repeat;} a.down {background: transparent url(/images/down_off.png) no-repeat;}
a.down:hover {background: transparent url(../images/down_on.png) no-repeat;} a.down:hover {background: transparent url(/images/down_on.png) no-repeat;}
a.to_bottom {background: transparent url(../images/bottom_off.png) no-repeat;} a.to_bottom {background: transparent url(/images/bottom_off.png) no-repeat;}
a.to_bottom:hover {background: transparent url(../images/bottom_on.png) no-repeat;} a.to_bottom:hover {background: transparent url(/images/bottom_on.png) no-repeat;}
a.show_notes, a.link_to_notes {background-image: url(../images/notes_off.png); background-repeat: no-repeat; padding: 1px; background-color: transparent;} a.show_notes, a.link_to_notes {background-image: url(/images/notes_off.png); background-repeat: no-repeat; padding: 1px; background-color: transparent;}
a.show_notes:hover, a.link_to_notes:hover {background-image: url(../images/notes_on.png); background-repeat: no-repeat; padding: 1px; background-color: transparent;} a.show_notes:hover, a.link_to_notes:hover {background-image: url(/images/notes_on.png); background-repeat: no-repeat; padding: 1px; background-color: transparent;}
/* Structural divs */ /* Structural divs */
@ -180,7 +180,7 @@ a.show_notes:hover, a.link_to_notes:hover {background-image: url(../images/notes
height: 100%; height: 100%;
z-index: 102; z-index: 102;
text-align: center; text-align: center;
background-image:url("../images/trans70.png"); background-image:url("/images/trans70.png");
} }
#overlay #new-recurring-todo, #overlay #edit-recurring-todo { #overlay #new-recurring-todo, #overlay #edit-recurring-todo {
@ -997,7 +997,7 @@ ul#prefs {list-style-type: disc; margin-left: 15px;}
font-style:oblique; font-style:oblique;
} }
input.open_id { input.open_id {
background: url(../images/open-id-login-bg.gif) no-repeat; background: url(/images/open-id-login-bg.gif) no-repeat;
background-color: #fff; background-color: #fff;
background-position: 0 50%; background-position: 0 50%;
color: #000; color: #000;
@ -1146,28 +1146,28 @@ button.positive, .widgets a.positive{
color:#fff; color:#fff;
} }
.tracks__waiting { .tracks__waiting {
background-image:url('../images/waiting.gif'); background-image:url('/images/waiting.gif');
background-repeat:no-repeat; background-repeat:no-repeat;
background-position:center center; background-position:center center;
background-color:white; background-color:white;
} }
.bigWaiting { .bigWaiting {
background-image:url('../images/bigWaiting.gif'); background-image:url('/images/bigWaiting.gif');
background-repeat:no-repeat; background-repeat:no-repeat;
background-position:center 20%; background-position:center 20%;
background-color:white; background-color:white;
} }
.blackWaiting { .blackWaiting {
background-image:url('../images/blackWaiting.gif'); background-image:url('/images/blackWaiting.gif');
background-repeat:no-repeat; background-repeat:no-repeat;
background-position:center center; background-position:center center;
background-color:black; background-color:black;
} }
.bigBlackWaiting { .bigBlackWaiting {
background-image:url('../images/bigBlackWaiting.gif'); background-image:url('/images/bigBlackWaiting.gif');
background-repeat:no-repeat; background-repeat:no-repeat;
background-position:center center; background-position:center center;
background-color:black; background-color:black;

View file

@ -1,3 +1,27 @@
<%
def today
Time.zone.now.beginning_of_day.to_s(:db)
end
def next_week
1.week.from_now.beginning_of_day.to_s(:db)
end
def last_week
1.week.ago.beginning_of_day.to_s(:db)
end
def two_weeks_ago
2.weeks.ago.beginning_of_day.to_s(:db)
end
def two_weeks_hence
2.weeks.from_now.beginning_of_day.to_s(:db)
end
%>
1: 1:
id: 1 id: 1
user_id: 1 user_id: 1

View file

@ -18,4 +18,9 @@ class DataControllerTest < Test::Rails::TestCase
login_as :admin_user login_as :admin_user
get :csv_notes get :csv_notes
end end
def test_yml_export_comleted_without_error
login_as :admin_user
get :yaml_export
end
end end

View file

@ -5,4 +5,5 @@ assert_context_count_incremented do
type "todo_description", "a new action" type "todo_description", "a new action"
type "todo_context_name", "Brand new context" type "todo_context_name", "Brand new context"
click "css=#todo-form-new-action .submit_box button" click "css=#todo-form-new-action .submit_box button"
assert_confirmation "New context \"Brand new context\" will be also created. Are you sure?"
end end

View file

@ -6,4 +6,5 @@ assert_context_count_incremented do
type "todo_project_name", "pppp" type "todo_project_name", "pppp"
type "todo_context_name", "cccc" type "todo_context_name", "cccc"
click "css=#todo-form-new-action .submit_box button" click "css=#todo-form-new-action .submit_box button"
assert_confirmation "New context \"cccc\" will be also created. Are you sure?"
end end

View file

@ -5,4 +5,5 @@ assert_context_count_incremented do
type "todo_description", "a new action" type "todo_description", "a new action"
type "todo_context_name", "Brand new context" type "todo_context_name", "Brand new context"
click "css=#todo-form-new-action .submit_box button" click "css=#todo-form-new-action .submit_box button"
assert_confirmation "New context \"Brand new context\" will be also created. Are you sure?"
end end

View file

@ -7,6 +7,7 @@ assert_context_count_incremented do
type "todo_project_name", "None" type "todo_project_name", "None"
type "todo_show_from", "1/1/2030" type "todo_show_from", "1/1/2030"
click "css=#todo-form-new-action .submit_box button" click "css=#todo-form-new-action .submit_box button"
assert_confirmation "New context \"errands\" will be also created. Are you sure?"
end end
wait_for_not_visible "tickler-empty-nd" wait_for_not_visible "tickler-empty-nd"
wait_for_element_present "xpath=//div[@class='item-container'] //a[@title='01/01/2030']" wait_for_element_present "xpath=//div[@class='item-container'] //a[@title='01/01/2030']"

View file

@ -6,4 +6,5 @@ assert_context_count_incremented do
type "todo_context_name", "Brand new context" type "todo_context_name", "Brand new context"
type "todo_show_from", "1/1/2030" type "todo_show_from", "1/1/2030"
click "css=#todo-form-new-action .submit_box button" click "css=#todo-form-new-action .submit_box button"
assert_confirmation "New context \"Brand new context\" will be also created. Are you sure?"
end end

View file

@ -9,10 +9,11 @@ class BundleFu
def bundle_files(filenames=[]) def bundle_files(filenames=[])
output = "" output = ""
filenames.each{ |filename| filenames.each{ |filename|
output << "/* --------- #{filename} --------- */ " filename_no_root = filename.sub(/^#{ActionController::Base.relative_url_root}/, '')
output << "/* --------- #{filename} - #{filename_no_root} --- ------ */ "
output << "\n" output << "\n"
begin begin
content = (File.read(File.join(RAILS_ROOT, "public", filename))) content = (File.read(File.join(RAILS_ROOT, "public", filename_no_root)))
rescue rescue
output << "/* FILE READ ERROR! */" output << "/* FILE READ ERROR! */"
next next

View file

@ -1,11 +1,15 @@
class BundleFu::CSSUrlRewriter class BundleFu::CSSUrlRewriter
class << self class << self
# rewrites a relative path to an absolute path, removing excess "../" and "./" # rewrites a relative path to an absolute path, removing excess "../" and "./"
# rewrite_relative_path("stylesheets/default/global.css", "../image.gif") => "/stylesheets/image.gif" # rewrite_relative_path("stylesheets/default/global.css", "../image.gif") => "#{rails_relative_root}/stylesheets/image.gif"
def rewrite_relative_path(source_filename, relative_url) def rewrite_relative_path(source_filename, relative_url)
relative_url = relative_url.to_s.strip.gsub(/["']/, "") relative_url = relative_url.to_s.strip.gsub(/["']/, "")
return relative_url if relative_url.first == "/" || relative_url.include?("://") return relative_url if relative_url.include?("://")
if ( relative_url.first == "/" )
return relative_url unless ActionController::Base.relative_url_root
return "#{ActionController::Base.relative_url_root}#{relative_url}"
end
elements = File.join("/", File.dirname(source_filename)).gsub(/\/+/, '/').split("/") elements = File.join("/", File.dirname(source_filename)).gsub(/\/+/, '/').split("/")
elements += relative_url.gsub(/\/+/, '/').split("/") elements += relative_url.gsub(/\/+/, '/').split("/")
@ -24,7 +28,9 @@ class BundleFu::CSSUrlRewriter
end end
end end
elements * "/" path = elements * "/"
return path unless ActionController::Base.relative_url_root
"#{ActionController::Base.relative_url_root}#{path}"
end end
# rewrite the URL reference paths # rewrite the URL reference paths