Initial import

git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@1 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
bsag 2005-01-09 11:59:57 +00:00
commit ec3ee77797
83 changed files with 3361 additions and 0 deletions

13
tracks/README_FIRST.txt Normal file
View file

@ -0,0 +1,13 @@
The main README.txt file is in tracks/doc/README.txt, and the change log in tracks/doc/CHANGENOTES.txt.
The database structure dump file (with some test contents) is in tracks/db/tracks_dump 03.01.2005.sql, which you can import into your database.
** IMPORTANT **
Before you do anything else, you need to copy certain files and rename the copy:
tracks/config/database.yml.tmpl -> tracks/config/database.yml
tracks/config/settings.yml.tmpl -> tracks/config/settings.yml
tracks/log.tmpl -> tracks/log
You need to put your settings into database.yml and settings.yml. Just leave the .tmpl versions as they are. I'm sorry to impose this extra step, but it's important for the subversion repository not to have your super-seekrit MySQL database user name and password checked in to the repository for all to see!

29
tracks/README_LOGIN Normal file
View file

@ -0,0 +1,29 @@
== Installation
Done generating the login system. but there are still a few things you have to do
manually. First open your application.rb and add
require_dependency "login_system"
to the top of the file and include the login system with
include LoginSystem
The beginning of your ApplicationController.
It should look something like this :
require_dependency "login_system"
class ApplicationController < ActionController::Base
include LoginSystem
After you have done the modifications the the AbstractController you can
import the user model into the database. This model is meant as an example
and you should extend it. If you just want to get things up and running you
can find some create table syntax in db/user_model.sql.
== Useage
Now you can go around and happily add "before_filter :login_required" to the controllers which you would like to protect.
If the user hits a controller with the login_required filter he will be redirected to the login page and redirected back after a successful login. You can find the login_system.rb in the lib/ directory. It comes with some comments which should help explain the general useage.

112
tracks/Rakefile Normal file
View file

@ -0,0 +1,112 @@
require 'rake'
require 'rake/testtask'
require 'rake/rdoctask'
$VERBOSE = nil
require File.dirname(__FILE__) + '/config/environment'
require 'code_statistics'
desc "Run all the tests on a fresh test database"
task :default => [ :clone_development_structure_to_test, :test_units, :test_functional ]
desc "Generate API documentatio, show coding stats"
task :doc => [ :appdoc, :stats ]
desc "Run the unit tests in test/unit"
Rake::TestTask.new("test_units") { |t|
t.libs << "test"
t.pattern = 'test/unit/*_test.rb'
t.verbose = true
}
desc "Run the functional tests in test/functional"
Rake::TestTask.new("test_functional") { |t|
t.libs << "test"
t.pattern = 'test/functional/*_test.rb'
t.verbose = true
}
desc "Generate documentation for the application"
Rake::RDocTask.new("appdoc") { |rdoc|
rdoc.rdoc_dir = 'doc/app'
rdoc.title = "Rails Application Documentation"
rdoc.options << '--line-numbers --inline-source'
rdoc.rdoc_files.include('doc/README_FOR_APP')
rdoc.rdoc_files.include('app/**/*.rb')
}
desc "Generate documentation for the Rails framework"
Rake::RDocTask.new("apidoc") { |rdoc|
rdoc.rdoc_dir = 'doc/api'
rdoc.title = "Rails Framework Documentation"
rdoc.options << '--line-numbers --inline-source'
rdoc.rdoc_files.include('README')
rdoc.rdoc_files.include('CHANGELOG')
rdoc.rdoc_files.include('vendor/railties/lib/breakpoint.rb')
rdoc.rdoc_files.include('vendor/railties/CHANGELOG')
rdoc.rdoc_files.include('vendor/railties/MIT-LICENSE')
rdoc.rdoc_files.include('vendor/activerecord/README')
rdoc.rdoc_files.include('vendor/activerecord/CHANGELOG')
rdoc.rdoc_files.include('vendor/activerecord/lib/active_record/**/*.rb')
rdoc.rdoc_files.exclude('vendor/activerecord/lib/active_record/vendor/*')
rdoc.rdoc_files.include('vendor/actionpack/README')
rdoc.rdoc_files.include('vendor/actionpack/CHANGELOG')
rdoc.rdoc_files.include('vendor/actionpack/lib/action_controller/**/*.rb')
rdoc.rdoc_files.include('vendor/actionpack/lib/action_view/**/*.rb')
rdoc.rdoc_files.include('vendor/actionmailer/README')
rdoc.rdoc_files.include('vendor/actionmailer/CHANGELOG')
rdoc.rdoc_files.include('vendor/actionmailer/lib/action_mailer/base.rb')
}
desc "Report code statistics (KLOCs, etc) from the application"
task :stats do
CodeStatistics.new(
["Helpers", "app/helpers"],
["Controllers", "app/controllers"],
["Functionals", "test/functional"],
["Models", "app/models"],
["Units", "test/unit"]
).to_s
end
desc "Recreate the test databases from the development structure"
task :clone_development_structure_to_test => [ :db_structure_dump, :purge_test_database ] do
if ActiveRecord::Base.configurations["test"]["adapter"] == "mysql"
ActiveRecord::Base.establish_connection(:test)
ActiveRecord::Base.connection.execute('SET foreign_key_checks = 0')
IO.readlines("db/development_structure.sql").join.split("\n\n").each do |table|
ActiveRecord::Base.connection.execute(table)
end
elsif ActiveRecord::Base.configurations["test"]["adapter"] == "postgresql"
`psql -U #{ActiveRecord::Base.configurations["test"]["username"]} -f db/development_structure.sql #{ActiveRecord::Base.configurations["test"]["database"]}`
elsif ActiveRecord::Base.configurations["test"]["adapter"] == "sqlite"
`sqlite #{ActiveRecord::Base.configurations["test"]["dbfile"]} < db/development_structure.sql`
end
end
desc "Dump the database structure to a SQL file"
task :db_structure_dump do
if ActiveRecord::Base.configurations["development"]["adapter"] == "mysql"
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations["development"])
File.open("db/development_structure.sql", "w+") { |f| f << ActiveRecord::Base.connection.structure_dump }
elsif ActiveRecord::Base.configurations["development"]["adapter"] == "postgresql"
`pg_dump -U #{ActiveRecord::Base.configurations["development"]["username"]} -s -f db/development_structure.sql #{ActiveRecord::Base.configurations["development"]["database"]}`
elsif ActiveRecord::Base.configurations["development"]["adapter"] == "sqlite"
`sqlite #{ActiveRecord::Base.configurations["development"]["dbfile"]} .schema > db/development_structure.sql`
end
end
desc "Drop the test database and bring it back again"
task :purge_test_database do
if ActiveRecord::Base.configurations["test"]["adapter"] == "mysql"
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations["development"])
ActiveRecord::Base.connection.recreate_database(ActiveRecord::Base.configurations["test"]["database"])
elsif ActiveRecord::Base.configurations["test"]["adapter"] == "postgresql"
`dropdb -U #{ActiveRecord::Base.configurations["test"]["username"]} #{ActiveRecord::Base.configurations["test"]["database"]}`
`createdb -U #{ActiveRecord::Base.configurations["test"]["username"]} #{ActiveRecord::Base.configurations["test"]["database"]}`
elsif ActiveRecord::Base.configurations["test"]["adapter"] == "sqlite"
File.delete(ActiveRecord::Base.configurations["test"]["dbfile"]) if File.exist?(ActiveRecord::Base.configurations["test"]["dbfile"])
end
end

View file

@ -0,0 +1,18 @@
# The filters added to this controller will be run for all controllers in the application.
# Likewise will all the methods added be available for all controllers.
require_dependency "login_system"
require_dependency "redcloth"
require 'date'
$delete_img = "<img src=\"/images/delete.png\" width=\"10\" height=\"10\" />"
$edit_img = "<img src=\"/images/edit.png\" width=\"10\" height=\"10\" />"
$notes_img = "<img src=\"/images/notes.png\" width=\"10\" height=\"10\" />"
$done_img = "<img src=\"/images/done.png\" width=\"16\" height=\"16\" />"
class ApplicationController < ActionController::Base
helper :application
include LoginSystem
end

View file

@ -0,0 +1,94 @@
class ContextController < ApplicationController
helper :context
model :project
scaffold :context
before_filter :login_required
layout "standard"
# Main method for listing contexts
# Set page title, and collect existing contexts in @contexts
#
def list
@page_title = "List Contexts"
@contexts = Context.find_all
end
# Called by a form button
# Parameters from form fields should be passed to create new context
#
def add_context
context = Context.new
context.name = @params["new_context"]["name"]
if context.save
flash["confirmation"] = "Succesfully created context"
redirect_to( :action => "list" )
else
flash["warning"] = "Couldn't add new context"
redirect_to( :action => "list" )
end
end
# Filter the contexts to show just the one passed in the URL
# e.g. <home>/context/show/<context_id> shows just <context_id>.
#
def show
@context = Context.find(@params["id"])
@places = Context.find_all
@projects = Project.find_all
@page_title = "Context: #{@context.name.capitalize}"
@not_done = Todo.find_all( "context_id=#{@context.id} AND done=0", "created DESC" )
end
# Called by a form button
# Parameters from form fields are passed to create new action
# in the selected context.
def add_item
item = Todo.new
item.attributes = @params["new_item"]
# Convert the date format entered (as set in config/settings.yml)
# to the mysql format YYYY-MM-DD
if @params["new_item"]["due"] != ""
date_fmt = app_configurations["formats"]["date"]
formatted_date = DateTime.strptime(@params["new_item"]["due"], "#{date_fmt}")
item.due = formatted_date.strftime("%Y-%m-%d")
else
item.due = "0000-00-00"
end
back_to = item.context_id
if item.save
flash["confirmation"] = "Succesfully added action to context"
redirect_to( :controller => "context", :action => "show", :id => "#{back_to}" )
else
flash["warning"] = "Could not add action to context"
redirect_to( :controller => "context", :action => "show", :id => "#{back_to}" )
end
end
# Fairly self-explanatory; deletes the context
# If the context contains actions, you'll get a warning dialogue.
# If you choose to go ahead, any actions in the context will also be deleted.
def destroy
context = Context.find(@params['id'])
if context.destroy
flash["confirmation"] = "Succesfully deleted context"
redirect_to( :action => "list" )
else
flash["warning"] = "Couldn't delete context"
redirect_to( :action => "list" )
end
end
end

View file

@ -0,0 +1,33 @@
# Produces an feeds of the next actions, both RSS and plain text
#
class FeedController < ApplicationController
helper :feed
model :todo, :context, :project
def index
end
# Builds an RSS feed for the latest 15 items
# This is fairly basic: it lists the action description as the title
# and the item context as the description
#
def na_feed
@not_done = Todo.find_all( "done=0", "created DESC" )
@headers["Content-Type"] = "text/xml; charset=utf-8"
end
# Builds a plain text page listing all the next actions,
# sorted by context. Showing notes doesn' make much sense here
# so they are omitted. You can use this with GeekTool to get your next actions
# on the desktop:
# curl http://url_for_the_app/feed/na_text
#
def na_text
@places = Context.find_all
@projects = Project.find_all
@not_done = Todo.find_all( "done=0", "context_id ASC" )
@headers["Content-Type"] = "text/plain; charset=utf-8"
end
end

View file

@ -0,0 +1,49 @@
class LoginController < ApplicationController
model :user
layout 'scaffold'
def login
case @request.method
when :post
if @session['user'] = User.authenticate(@params['user_login'], @params['user_password'])
flash['notice'] = "Login successful"
redirect_back_or_default :controller => "todo", :action => "list"
else
@login = @params['user_login']
@message = "Login unsuccessful"
end
end
end
def signup
case @request.method
when :post
@user = User.new(@params['user'])
if @user.save
@session['user'] = User.authenticate(@user.login, @params['user']['password'])
flash['notice'] = "Signup successful"
redirect_back_or_default :controller => "todo", :action => "list"
end
when :get
@user = User.new
end
end
def delete
if @params['id']
@user = User.find(@params['id'])
@user.destroy
end
redirect_back_or_default :controller => "todo", :action => "list"
end
def logout
@session['user'] = nil
end
def welcome
end
end

View file

@ -0,0 +1,107 @@
class ProjectController < ApplicationController
helper :project
model :context
model :todo
scaffold :project
before_filter :login_required
layout "standard"
# Main method for listing projects
# Set page title, and collect existing projects in @projects
#
def list
@page_title = "List Projects"
@projects = Project.find_all
end
# Filter the projects to show just the one passed in the URL
# e.g. <home>/project/show/<project_id> shows just <project_id>.
#
def show
@project = Project.find(@params["id"])
@places = Context.find_all
@page_title = "Project: #{@project.name}"
@not_done = Todo.find_all( "project_id=#{@project.id} AND done=0", "created DESC" )
end
# Called by a form button
# Parameters from form fields should be passed to create new project
#
def add_project
project = Project.new
project.name = @params["new_project"]["name"]
if project.save
flash["confirmation"] = "Succesfully added project"
redirect_to( :action => "list" )
else
flash["warning"] = "Couldn't add project"
redirect_to( :action => "list" )
end
end
# Called by a form button
# Parameters from form fields should be passed to create new item
#
def add_item
item = Todo.new
item.attributes = @params["new_item"]
# Convert the date format entered (as set in config/settings.yml)
# to the mysql format YYYY-MM-DD
if @params["new_item"]["due"] != ""
date_fmt = app_configurations["formats"]["date"]
formatted_date = DateTime.strptime(@params["new_item"]["due"], "#{date_fmt}")
item.due = formatted_date.strftime("%Y-%m-%d")
else
item.due = "0000-00-00"
end
back_to = item.project_id
if item.save
flash["confirmation"] = "Successfully added next action to project"
redirect_to( :controller => "project", :action => "show", :id => "#{back_to}" )
else
flash["warning"] = "Couldn't add next action to project"
redirect_to( :controller => "project", :action => "show", :id => "#{back_to}" )
end
end
def destroy
project = Project.find( @params['id'] )
if project.destroy
flash["confirmation"] = "Succesfully deleted project"
redirect_to( :action => "list" )
else
flash["warning"] = "Couldn't delete project"
redirect_to( :action => "list" )
end
end
# Toggles the 'done' status of the action
def toggle_check
item = Todo.find( @params['id'] )
case item.done
when 0: item.done = 1; item.completed = Time.now()
when 1: item.done = 0; item.completed = nil
end
if item.save
flash["confirmation"] = "Marked next action as completed"
redirect_to( :action => "list" )
else
flash["warning"] = "Couldn't mark next action as completed"
redirect_to( :action => "list" )
end
end
end

View file

@ -0,0 +1,111 @@
class TodoController < ApplicationController
helper :todo
model :context
model :project
scaffold :todo
before_filter :login_required
layout "standard"
# Main method for listing tasks
# Set page title, and fill variables with contexts and done and not-done tasks
#
def list
@page_title = "List tasks"
@places = Context.find_all
@projects = Project.find_all
@not_done = Todo.find_all( "done=0", "completed DESC" )
@done = Todo.find_all( "done=1", "completed DESC", 5 )
end
# List the completed tasks, sorted by completion date
#
def completed
@page_title = "Completed tasks"
@done = Todo.find_all( "done=1", "completed DESC" )
end
# Called by a form button
# Parameters from form fields should be passed to create new item
#
def add_item
item = Todo.new
item.attributes = @params["new_item"]
# Convert the date format entered (as set in config/settings.yml)
# to the mysql format YYYY-MM-DD
if @params["new_item"]["due"] != ""
date_fmt = app_configurations["formats"]["date"]
formatted_date = DateTime.strptime(@params["new_item"]["due"], "#{date_fmt}")
item.due = formatted_date.strftime("%Y-%m-%d")
else
item.due = "0000-00-00"
end
if item.save
flash["confirmation"] = "Next action was successfully added"
redirect_to( :action => "list" )
else
flash["warning"] = "Couldn't add the action"
redirect_to( :action => "list" )
end
end
def edit
@item = Todo.find(@params['id'])
@belongs = @item.project_id
@page_title = "Edit task: #{@item.description}"
@places = Context.find_all
@projects = Project.find_all
end
def update
@item = Todo.find(@params['item']['id'])
@item.attributes = @params['item']
if @item.save
flash["confirmation"] = 'Next action was successfully updated'
redirect_to :action => 'list'
else
flash["warning"] = 'Next action could not be updated'
redirect_to :action => 'list'
end
end
def destroy
item = Todo.find(@params['id'])
if item.destroy
flash["confirmation"] = "Next action was successfully deleted"
redirect_to :action => "list"
else
flash["warning"] = "Couldn't delete next action"
redirect_to :action => "list"
end
end
# Toggles the 'done' status of the action
#
def toggle_check
item = Todo.find(@params['id'])
case item.done
when 0: item.done = 1; item.completed = Time.now()
when 1: item.done = 0; item.completed = nil
end
if item.save
flash["confirmation"] = "Next action marked as completed"
redirect_to( :action => "list" )
else
flash["warning"] = "Couldn't mark action as completed"
redirect_to( :action => "list" )
end
end
end

View file

@ -0,0 +1,51 @@
# The methods added to this helper will be available to all templates in the application.
module ApplicationHelper
#require_dependency 'date'
def format_date(date)
# Convert a date object to the format specified
# in config/settings.yml
#
date_fmt = app_configurations["formats"]["date"]
formatted_date = date.strftime("#{date_fmt}")
end
def markdown(text)
# 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
#
RedCloth.new(text).to_html
end
def tag_object(object, tag)
# Wraps object in HTML tags, tag
#
tagged = "<#{tag}>#{object}</#{tag}>"
end
def due_date(due)
# Check due date in comparison to today's date
# Flag up date appropriately with a 'traffic light' colour code
#
if due == nil
return ""
end
@now = Date.today
@days = due-@now
case @days
# overdue or due very soon! sound the alarm!
when -365..1
"<span class=\"red\">" + format_date(due) + "</span> "
# due 2-7 days away
when 2..7
"<span class=\"amber\">" + format_date(due) + "</span> "
# more than a week away - relax
else
"<span class=\"green\">" + format_date(due) + "</span> "
end
end
end

View file

@ -0,0 +1,2 @@
module ContextHelper
end

View file

@ -0,0 +1,34 @@
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,contexts,projects)
result_string = ""
for @place in @places
result_string << "\n" + @place.name.upcase + ":\n"
list.each do |@item|
if @item.context_id == @place.id
if @item.due
result_string << " [" + 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
end
return result_string
end
end

View file

@ -0,0 +1,18 @@
module LoginHelper
def render_errors(obj)
return "" unless obj
return "" unless @request.post?
tag = String.new
unless obj.valid?
tag << %{<ul class="objerrors">}
obj.errors.each_full { |message| tag << %{<li>#{message}</li>} }
tag << %{</ul>}
end
tag
end
end

View file

@ -0,0 +1,2 @@
module ProjectHelper
end

View file

@ -0,0 +1,36 @@
module TodoHelper
def display_done(ary,context)
result_string = ""
result_string << "<ul>"
ary.each do |@item|
result_string << "<li>" + @item.description + " "
# Item should have a completion date if it is done
# This is just a sanity check
#
if @item.completed != nil
result_string << "[completed: " + format_date(@item.completed) + "]" + " "
end
result_string << "in " + @item.context['name'].capitalize + "</li>"
end
result_string << "</ul>"
return result_string
end
def count_items(items, context)
# Count the number of items in the selected context
#
count = 0
for item in items
if item.context['name'] == context
count += 1
end
end
return count
end
end

View file

@ -0,0 +1,3 @@
class Context < ActiveRecord::Base
has_many :todo, :dependent => true
end

View file

@ -0,0 +1,3 @@
class Project < ActiveRecord::Base
has_many :todo, :dependent => true
end

16
tracks/app/models/todo.rb Normal file
View file

@ -0,0 +1,16 @@
class Todo < ActiveRecord::Base
belongs_to :context
belongs_to :project
def before_save
# Add a creation date (Ruby object format) to item before it's saved
# if there is no existing creation date (this prevents creation date
# being reset to completion date when item is completed)
#
if self.created == nil
self.created = Time.now()
end
end
end

30
tracks/app/models/user.rb Normal file
View file

@ -0,0 +1,30 @@
require 'digest/sha1'
# this model expects a certain database layout and its based on the name/login pattern.
class User < ActiveRecord::Base
def self.authenticate(login, pass)
find_first(["login = ? AND password = ?", login, sha1(pass)])
end
def change_password(pass)
update_attribute "password", self.class.sha1(pass)
end
protected
def self.sha1(pass)
Digest::SHA1.hexdigest("change-me--#{pass}--")
end
before_create :crypt_password
def crypt_password
write_attribute("password", self.class.sha1(password)) if password == @password_confirmation
end
validates_length_of :password, :login, :within => 5..40
validates_presence_of :password, :login
validates_uniqueness_of :login, :on => :create
validates_confirmation_of :password, :on => :create
end

View file

@ -0,0 +1,32 @@
<div id="display_box">
<table cellpadding="5" width="450">
<% row = 1 %>
<% for @context in @contexts %>
<% if row % 2 == 0 %>
<tr class="even_row">
<% else %>
<tr class="odd_row">
<% end %>
<td align="right" width="20"><%= @context.id.to_s %></td>
<td width="390"><%= link_to( "#{@context.name.capitalize}", :action => "show", :id => @context.id ) %></td>
<td width="40"><%= link_to($edit_img, { :action => "edit", :id => @context.id }, :title => "Edit item" ) + " " + link_to($delete_img, { :action => "destroy", :id => @context.id }, :title => "Delete item", :confirm => "Are you sure you want to delete this context: #{@context.name}. Any todos in this context will be deleted.") + " " %></td>
</tr>
<% row += 1 %>
<% end %>
</table>
</div><!- End of display_box -->
<div id="input_box">
<h2>Add context</h2>
<form method="post" action="add_context">
<label for="new_context_name">New context</label><br />
<%= text_field("new_context", "name") %>
<br />
<input type="submit" value="Add context">
</form>
</div>
<% if @flash["confirmation"] %><div class="confirmation"><%= @flash["confirmation"] %></div><% end %>
<% if @flash["warning"] %><div class="warning"><%= @flash["warning"] %></div><% end %>

View file

@ -0,0 +1,61 @@
<div id="display_box">
<div class="contexts">
<h2><%= @context.name.capitalize %></h2>
<ul>
<% for @item in @not_done %>
<li>
<div class="box">
<%= check_box( "item", "done", "onclick" => "document.location.href='/todo/toggle_check/#{@item.id}'" ) %>
</div>
<div class="description">
<%= due_date(@item.due) %>
<%= @item.description %>
<% if @item.project_id %>
<%= link_to( "[P]", { :controller => "project", :action => "show", :id => @item.project_id }, :title => "View project: #{@item.project['name']}" ) %>
<% end %>
</div>
<div class="tools">
<%= link_to($edit_img, { :controller => "todo", :action => "edit", :id => @item.id }, :title => "Edit item") + " " + link_to($delete_img, { :controller => "todo", :action => "destroy", :id => @item.id }, :title => "Delete item", :confirm => "Are you sure you want to delete this entry: #{@item.description}") + " " %>
<% if @item.notes? %>
<%= "<a href=\"javascript:toggle('" + @item.id.to_s + "')\" title=\"Show notes\">" + $notes_img + "</a>" %></div>
<% m_notes = markdown(@item.notes) %>
<%= "<div class=\"notes\" id=\"" + @item.id.to_s + "\">" + m_notes + "</div>" %>
<% else %>
</div>
<% end %>
</li>
<% end %>
</ul>
</div>
</div><!- End of display_box -->
<div id="input_box">
<h2>Add next action to this context</h2>
<%= form_tag( :controller => "context", :action => "add_item") %>
<%= hidden_field( "new_item", "context_id", "value" => "#{@context.id}") %>
<label for="new_item_description">Next action</label><br />
<%= text_field( "new_item", "description" ) %>
<br />
<label for="new_item_notes">Notes</label><br />
<%= text_area( "new_item", "notes", "cols" => 40, "rows" => 15 ) %>
<br />
<label for="new_item_project_id">Project</label><br />
<select name="new_item[project_id]" id="new_item_project_id">
<option value="" selected>None</option>
<% for @project in @projects %>
<option value="<%= @project.id %>"><%= @project.name %></option>
<% end %>
</select><br />
<label for="new_item_due">Due</label><br />
<%= text_field( "new_item", "due", {"size" => 10, "maxlength" => 10} ) %>
<br />
<input type="submit" value="Add item">
</form>
</div><!-- End of input box -->
<% if @flash["confirmation"] %><div class="confirmation"><%= @flash["confirmation"] %></div><% end %>
<% if @flash["warning"] %><div class="warning"><%= @flash["warning"] %></div><% end %>

View file

@ -0,0 +1,14 @@
xml.rss("version" => "2.0", "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
xml.channel do
xml.title("Tracks - Next Actions")
xml.link("http://#{@request.host}:#{@request.port}/todo/list")
xml.description("Lists the last 15 undone next actions")
@not_done.each { |i|
xml.item do
xml.title(i.description)
xml.link("http://#{@request.host}:#{@request.port}/context/show/#{i.context_id}")
xml.description(i.context['name'].capitalize)
end
}
end
end

View file

@ -0,0 +1 @@
<%= build_text_page( @not_done, @places, @projects ) %>

View file

@ -0,0 +1,10 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Login</title>
<link href="/stylesheets/scaffold.css" rel="stylesheet" type="text/css" />
</head>
<body>
<%= @content_for_layout %>
</body>
</html>

View file

@ -0,0 +1,38 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style type="text/css" media="screen">
@import url(/stylesheets/standard.css);
</style>
<script type="text/javascript" src="/javascripts/toggle_notes.js"></script>
<title><%= @page_title %></title>
</head>
<body onload="javascript:toggleAll('notes','none')">
<div>
<h1>
<% if @not_done %>
<span class="badge"><%= @not_done.length %></span>
<% end %>
<%= today = Time.now; datestamp = today.strftime("%A, %e %B %Y") %></h1>
</div>
<div id="navcontainer">
<ul id="navlist">
<li><%= link_to( "Home", :controller => "todo", :action => "list" ) %></li>
<li><%= link_to( "Contexts", :controller => "context", :action => "list" ) %></li>
<li><%= link_to( "Projects", :controller => "project", :action => "list" ) %></li>
<li><%= link_to( "Completed", :controller => "todo", :action => "completed" ) %></li>
<li><a href="javascript:toggleAll('notes','block')" title="Show all notes">Show</a></li>
<li><a href="javascript:toggleAll('notes','none')" title="Show all notes">Hide</a></li>
<li><%= link_to "<span style=\"font-family: verdana, sans-serif; font-size: 10px; font-weight:bold; text-decoration:none; color: white; background-color: #F60; border:1px solid;
border-color: #FC9 #630 #330 #F96; padding:0px 3px 0px 3px; margin:0px;\">RSS</span>", { :controller => "feed", :action => "na_feed" }, :title => "Subscribe to RSS feed of next actions" %></li>
<li><%= link_to "<span style=\"font-family: verdana, sans-serif; font-size: 10px; font-weight:bold; text-decoration:none; color: white; background-color: #F60; border:1px solid;
border-color: #FC9 #630 #330 #F96; padding:0px 3px 0px 3px; margin:0px;\">TXT</span>", { :controller => "feed", :action => "na_text" }, :title => "View a plain text list of next actions" %></li>
<li><%= link_to "Logout &#187;", :controller => "login", :action=>"logout"%></li>
</ul>
</div>
<%= @content_for_layout %>
<div id="footer">made with <a href="http://rubyonrails.org">Ruby on Rails</a></div>
</body>
</html>

View file

@ -0,0 +1,22 @@
<%= start_form_tag :action=> "login" %>
<div title="Account login" id="loginform" class="form">
<h3>Please log in to use Tracks:</h3>
<% if @message %>
<div id="message"><%= @message %></div>
<% end %>
<label for="user_login">Login:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</label>
<input type="text" name="user_login" id="user_login" size="30" value=""/><br/>
<label for="user_password">Password:</label>
<input type="password" name="user_password" id="user_password" size="30"/>
<br/>
<input type="submit" name="login" value="Login &#187;" class="primary" />
</div>
<%= end_form_tag %>

View file

@ -0,0 +1,10 @@
<div class="memo">
<h3>Logoff</h3>
<p>You are now logged out of the system...</p>
<%= link_to "&#171; login", :action=>"login"%>
</div>

View file

@ -0,0 +1,17 @@
<%= start_form_tag :action=> "signup" %>
<div title="Account signup" id="signupform" class="form">
<h3>Signup</h3>
<%= render_errors @user %><br/>
<label for="user_login">Desired login:</label><br/>
<%= text_field "user", "login", :size => 30 %><br/>
<label for="user_password">Choose password:</label><br/>
<%= password_field "user", "password", :size => 30 %><br/>
<label for="user_password_confirmation">Confirm password:</label><br/>
<%= password_field "user", "password_confirmation", :size => 30 %><br/>
<input type="submit" value="Signup &#187;" class="primary" />
<%= end_form_tag %>

View file

@ -0,0 +1,13 @@
<div class="memo">
<h3>Welcome</h3>
<p>You are now logged into the system...</p>
<p>
Since you are here it's safe to assume the application never called store_location, otherwise
you would have been redirected somewhere else after a successful login.
</p>
<%= link_to "&#171; logout", :action=>"logout"%>
</div>

View file

@ -0,0 +1,32 @@
<div id="display_box">
<table cellpadding="5" width="450">
<% row = 1 %>
<% for @project in @projects %>
<% if row % 2 == 0 %>
<tr class="even_row">
<% else %>
<tr class="odd_row">
<% end %>
<td align="right" width="20"><%= @project.id.to_s %></td>
<td width="390"><%= link_to ( "#{@project.name}", :action => "show", :id => @project.id ) %></td>
<td width="40"><%= link_to( $edit_img, { :action => "edit", :id => @project.id }, :title => "Edit item" ) + " " + link_to($delete_img, { :action => "destroy", :id => @project.id }, :title => "Delete item", :confirm => "Are you sure you want to delete this context: #{@project.name}. Any todos in this context will be deleted." ) + " " %></td>
</tr>
<% row += 1 %>
<% end %>
</table>
</div><!- End of display_box -->
<div id="input_box">
<h2>Add project</h2>
<form method="post" action="add_project">
<label for="new_project_name">New Project</label><br />
<%= text_field( "new_project", "name" ) %>
<br />
<input type="submit" value="Add project">
</form>
</div>
<% if @flash["confirmation"] %><div class="confirmation"><%= @flash["confirmation"] %></div><% end %>
<% if @flash["warning"] %><div class="warning"><%= @flash["warning"] %></div><% end %>

View file

@ -0,0 +1,65 @@
<div id="display_box">
<div class="contexts">
<h2><%= @project.name %></h2>
<% if @not_done == [] %>
<p>There are no next actions yet in this project</p>
<% else %>
<ul>
<% for @item in @not_done %>
<li>
<div class="box">
<%= check_box( "item", "done", "onclick" => "document.location.href='/todo/toggle_check/#{@item.id}'" ) %>
</div>
<div class="description">
<%= due_date( @item.due ) %>
<%= @item.description %>
<%= link_to( "[C]", { :controller => "context", :action => "show", :id => @item.context_id }, :title => "View context: #{@item.context['name'].capitalize}" ) %>
</div>
<div class="tools">
<%= link_to( $edit_img, { :controller => "todo", :action => "edit", :id => @item.id }, :title => "Edit item" ) + " " + link_to($delete_img, { :controller => "todo", :action => "destroy", :id => @item.id }, :title => "Delete item", :confirm => "Are you sure you want to delete this entry: #{@item.description}" ) + " " %>
<% if @item.notes? %>
<%= "<a href=\"javascript:toggle('" + @item.id.to_s + "')\" title=\"Show notes\">" + $notes_img + "</a>" %></div>
<% m_notes = markdown(@item.notes) %>
<%= "<div class=\"notes\" id=\"" + @item.id.to_s + "\">" + m_notes + "</div>" %>
<% else %>
</div>
<% end %>
</li>
<% end %>
</ul>
<% end %>
</div>
</div><!-- End of display box -->
<div id="input_box">
<h2>Add next action to this project</h2>
<%= form_tag( :controller => "project", :action => "add_item") %>
<%= hidden_field( "new_item", "project_id", "value" => "#{@project.id}") %>
<label for="new_item_description">Next action</label><br />
<%= text_field( "new_item", "description" ) %>
<br />
<label for="new_item_notes">Notes</label><br />
<%= text_area( "new_item", "notes", "cols" => 40, "rows" => 15 ) %>
<br />
<label for="new_item_context_id">Context</label><br />
<select name="new_item[context_id]" id="new_item_context_id">
<% for @place in @places %>
<option value="<%= @place.id %>"><%= @place.name.capitalize %></option>
<% end %>
</select>
<br />
<label for="new_item_due">Due</label><br />
<%= text_field( "new_item", "due", {"size" => 10, "maxlength" => 10} ) %>
<br />
<input type="submit" value="Add item">
</form>
</div><!-- End of input box -->
<% if @flash["confirmation"] %><div class="confirmation"><%= @flash["confirmation"] %></div><% end %>
<% if @flash["warning"] %><div class="warning"><%= @flash["warning"] %></div><% end %>

View file

@ -0,0 +1,29 @@
<% @item = done %>
<li>
<% if @item.completed %>
<div class="box">
<%= $done_img %>
</div>
<div class="description">
<span class="grey"><%= format_date( @item.completed ) %></span>
<%= " " + @item.description + " "%>
<% if @item.project_id %>
<%= "(" + @item.context['name'].capitalize + ", " + @item.project['name'] + ")" %>
<% else %>
<%= "(" + @item.context['name'].capitalize + ")" %>
<% end %>
<% if @item.due %>
<%= " - was due on " + format_date( @item.due ) %>
<% end %>
<% if @item.notes? %>
<%= "<a href=\"javascript:toggle('" + @item.id.to_s + "')\" title=\"Show notes\">" + $notes_img + "</a>" %>
<% m_notes = markdown( @item.notes ) %>
<%= "<div class=\"notes\" id=\"" + @item.id.to_s + "\">" + m_notes + "</div>" %>
<% end %>
</div>
<% end %>
</li>

View file

@ -0,0 +1,10 @@
<div id="display_box_projects">
<div class="contexts">
<h2>Completed items</h2>
<ul>
<%= render_collection_of_partials "done", @done %>
</ul>
</div>
</div><!- End of display_box -->

View file

@ -0,0 +1,48 @@
<div id="display_box">
<h2>Update task</h2>
<form action="/todo/update" method="post">
<%= hidden_field( "item", "id" ) %>
<p><label for="item_description">Description</label><br />
<%= text_field( "item", "description" ) %></p>
<p><label for="item_notes">Notes</label><br />
<%= text_area( "item", "notes" ) %></p>
<p><label for="item_context_id">Context</label><br />
<select name="item[context_id]" id="item_context_id">
<% for @place in @places %>
<% if @place.id == @item.context_id %>
<option value="<%= @place.id %>" selected="selected"><%= @place.name.capitalize %></option>
<% else %>
<option value="<%= @place.id %>"><%= @place.name.capitalize %></option>
<% end %>
<% end %>
</select></p>
<p><label for="new_item_project_id">Project</label><br />
<select name="item[project_id]" id="item_project_id">
<% if @belongs == nil %>
<option value="" selected="selected">None</option>
<% end %>
<% for @project in @projects %>
<% if @project.id == @belongs %>
<option value="<%= @project.id %>" selected="selected"><%= @project.name %></option>
<% else %>
<option value="<%= @project.id %>"><%= @project.name %></option>
<% end %>
<% end %>
</select></p>
<p><label for="item_due">Due (YYYY-MM-DD)</label><br />
<%= text_field( "item", "due" ) %></p>
<p><input type="submit" value="Update" /></p>
</form>
<%= link_to 'Cancel', :action => 'list' %>
</div>
<% if @flash["confirmation"] %><div class="confirmation"><%= @flash["confirmation"] %></div><% end %>
<% if @flash["warning"] %><div class="warning"><%= @flash["warning"] %></div><% end %>

View file

@ -0,0 +1,89 @@
<div id="display_box">
<% for @place in @places %>
<% heading = false %>
<% for @item in @not_done %>
<% if @place.name == @item.context['name'] %>
<% if ( Todo.find_all( "context_id=#{@item.context['id']}" ) && heading == false ) %>
<div class="contexts">
<h2><%= link_to( "#{@item.context['name'].capitalize}", :controller => "context", :action => "show", :id => @item.context_id ) %></h2>
<ul>
<% heading = true %>
<% end %>
<li>
<div class="box">
<%= check_box( "item", "done", "onclick" => "document.location.href='/todo/toggle_check/#{@item.id}'" ) %>
</div>
<div class="description">
<%= due_date( @item.due ) %>
<%= @item.description %>
<% if @item.project_id %>
<%= link_to( "[P]", { :controller => "project", :action => "show", :id => @item.project_id }, :title => "View project: #{@item.project['name']}" ) %>
<% end %>
</div>
<div class="tools">
<%= link_to( $edit_img, { :action => "edit", :id => @item.id }, :title => "Edit item" ) + " " + link_to($delete_img, { :action => "destroy", :id => @item.id }, :title => "Delete item", :confirm => "Are you sure you want to delete this entry: #{@item.description}" ) + " " %>
<% if @item.notes? %>
<%= "<a href=\"javascript:toggle('" + @item.id.to_s + "')\" title=\"Show notes\">" + $notes_img + "</a>" %></div>
<% m_notes = markdown( @item.notes ) %>
<%= "<div class=\"notes\" id=\"" + @item.id.to_s + "\">" + m_notes + "</div>" %>
<% else %>
</div>
<% end %>
</li>
<% end %>
<% end %>
<% if heading == true %>
</ul>
</div>
<% end %>
<% end %>
<div class="contexts">
<h2>Last 5 completed actions</h2>
<ul>
<%= render_collection_of_partials "done", @done %>
</ul>
</div>
</div><!- End of display_box -->
<div id="input_box">
<h2>Add next action</h2>
<form method="post" action="add_item">
<label for="new_item_description">Next action</label><br />
<%= text_field( "new_item", "description" ) %>
<br />
<label for="new_item_notes">Notes</label><br />
<%= text_area( "new_item", "notes", "cols" => 40, "rows" => 15 ) %>
<br />
<label for="new_item_context_id">Context</label><br />
<select name="new_item[context_id]" id="new_item_context_id">
<% for @place in @places %>
<option value="<%= @place.id %>"><%= @place.name.capitalize %></option>
<% end %>
</select>
<br />
<label for="new_item_project_id">Project</label><br />
<select name="new_item[project_id]" id="new_item_project_id">
<option value="" selected>None</option>
<% for @project in @projects %>
<option value="<%= @project.id %>"><%= @project.name %></option>
<% end %>
</select>
<br />
<label for="new_item_due">Due</label><br />
<%= text_field( "new_item", "due", {"size" => 10, "maxlength" => 10} ) %>
<br />
<input type="submit" value="Add item">
</form>
</div>
<% if @flash["confirmation"] %><div class="confirmation"><%= @flash["confirmation"] %></div><% end %>
<% if @flash["warning"] %><div class="warning"><%= @flash["warning"] %></div><% end %>

View file

@ -0,0 +1,20 @@
development:
adapter: mysql
database: tracks
host: localhost
username: root
password:
test:
adapter: mysql
database: tracks_test
host: localhost
username: root
password:
production:
adapter: mysql
database: tracks
host: localhost
username: root
password:

View file

@ -0,0 +1,63 @@
RAILS_ROOT = File.dirname(__FILE__) + "/../"
RAILS_ENV = ENV['RAILS_ENV'] || 'development'
# Mocks first.
ADDITIONAL_LOAD_PATHS = ["#{RAILS_ROOT}/test/mocks/#{RAILS_ENV}"]
# Then model subdirectories.
ADDITIONAL_LOAD_PATHS.concat(Dir["#{RAILS_ROOT}/app/models/[_a-z]*"])
# Followed by the standard includes.
ADDITIONAL_LOAD_PATHS.concat %w(
app
app/models
app/controllers
app/helpers
config
lib
vendor
).map { |dir| "#{RAILS_ROOT}/#{dir}" }
# Prepend to $LOAD_PATH
ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) }
# Require Rails gems.
require 'rubygems'
require_gem 'activerecord'
require_gem 'actionpack'
require_gem 'actionmailer'
require_gem 'rails'
# Environment-specific configuration.
require_dependency "environments/#{RAILS_ENV}"
ActiveRecord::Base.configurations = YAML::load(File.open("#{RAILS_ROOT}/config/database.yml"))
ActiveRecord::Base.establish_connection
# Configure defaults if the included environment did not.
begin
RAILS_DEFAULT_LOGGER = Logger.new("#{RAILS_ROOT}/log/#{RAILS_ENV}.log")
rescue StandardError
RAILS_DEFAULT_LOGGER = Logger.new(STDERR)
RAILS_DEFAULT_LOGGER.level = Logger::WARN
RAILS_DEFAULT_LOGGER.warn(
"Rails Error: Unable to access log file. Please ensure that log/#{RAILS_ENV}.log exists and is chmod 0777. " +
"The log level has been raised to WARN and the output directed to STDERR until the problem is fixed."
)
end
[ActiveRecord::Base, ActionController::Base, ActionMailer::Base].each do |klass|
klass.logger ||= RAILS_DEFAULT_LOGGER
end
[ActionController::Base, ActionMailer::Base].each do |klass|
klass.template_root ||= "#{RAILS_ROOT}/app/views/"
end
# Include your app's configuration here:
def app_configurations
YAML::load(File.open("#{RAILS_ROOT}/config/settings.yml"))
end

View file

@ -0,0 +1,3 @@
Dependencies.mechanism = :load
ActionController::Base.consider_all_requests_local = true
BREAKPOINT_SERVER_PORT = 42531

View file

@ -0,0 +1,2 @@
Dependencies.mechanism = :require
ActionController::Base.consider_all_requests_local = false

View file

@ -0,0 +1,3 @@
Dependencies.mechanism = :require
ActionController::Base.consider_all_requests_local = true
ActionMailer::Base.delivery_method = :test

View file

@ -0,0 +1,2 @@
formats:
date: %d/%m/%Y

View file

@ -0,0 +1,88 @@
# CocoaMySQL dump
# Version 0.5
# http://cocoamysql.sourceforge.net
#
# Host: localhost (MySQL 4.0.20-max)
# Database: todo
# Generation Time: 2005-01-03 14:14:18 +0000
# ************************************************************
# Dump of table contexts
# ------------------------------------------------------------
CREATE TABLE `contexts` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL default '',
PRIMARY KEY (`id`)
) TYPE=MyISAM;
INSERT INTO `contexts` (`id`,`name`) VALUES ("1","agenda");
INSERT INTO `contexts` (`id`,`name`) VALUES ("2","call");
INSERT INTO `contexts` (`id`,`name`) VALUES ("3","email");
INSERT INTO `contexts` (`id`,`name`) VALUES ("4","errand");
INSERT INTO `contexts` (`id`,`name`) VALUES ("5","lab");
INSERT INTO `contexts` (`id`,`name`) VALUES ("6","library");
INSERT INTO `contexts` (`id`,`name`) VALUES ("7","freetime");
INSERT INTO `contexts` (`id`,`name`) VALUES ("8","office");
INSERT INTO `contexts` (`id`,`name`) VALUES ("11","waiting-for");
# Dump of table projects
# ------------------------------------------------------------
CREATE TABLE `projects` (
`id` int(11) NOT NULL auto_increment,
`name` varchar(255) NOT NULL default '',
PRIMARY KEY (`id`)
) TYPE=MyISAM;
INSERT INTO `projects` (`id`,`name`) VALUES ("1","Build a working time machine");
INSERT INTO `projects` (`id`,`name`) VALUES ("2","Make more money than Billy Gates");
INSERT INTO `projects` (`id`,`name`) VALUES ("3","Evict dinosaurs from the garden");
# Dump of table todos
# ------------------------------------------------------------
CREATE TABLE `todos` (
`id` int(11) NOT NULL auto_increment,
`context_id` int(11) NOT NULL default '0',
`description` varchar(100) NOT NULL default '',
`notes` text,
`done` tinyint(4) NOT NULL default '0',
`created` datetime NOT NULL default '0000-00-00 00:00:00',
`due` date default NULL,
`completed` datetime default NULL,
`project_id` int(11) default NULL,
PRIMARY KEY (`id`)
) TYPE=MyISAM;
INSERT INTO `todos` (`id`,`context_id`,`description`,`notes`,`done`,`created`,`due`,`completed`,`project_id`) VALUES ("1","1","Call Bill Gates to find out how much he makes per day","","0","2004-11-28 16:01:00","2004-10-30",NULL,"2");
INSERT INTO `todos` (`id`,`context_id`,`description`,`notes`,`done`,`created`,`due`,`completed`,`project_id`) VALUES ("52","2","Call dinosaur exterminator","Ask him if I need to hire a skip for the corpses.","0","2004-11-28 16:06:08","2004-11-30",NULL,"3");
INSERT INTO `todos` (`id`,`context_id`,`description`,`notes`,`done`,`created`,`due`,`completed`,`project_id`) VALUES ("53","4","Buy milk","","1","2004-11-28 16:06:31","0000-00-00","2004-11-28 16:06:42",NULL);
INSERT INTO `todos` (`id`,`context_id`,`description`,`notes`,`done`,`created`,`due`,`completed`,`project_id`) VALUES ("54","4","Buy bread","","1","2004-11-28 16:06:58","0000-00-00","2004-11-30 13:41:09",NULL);
INSERT INTO `todos` (`id`,`context_id`,`description`,`notes`,`done`,`created`,`due`,`completed`,`project_id`) VALUES ("55","5","Construct time dilation device","","0","2004-11-28 16:07:33","0000-00-00",NULL,"1");
INSERT INTO `todos` (`id`,`context_id`,`description`,`notes`,`done`,`created`,`due`,`completed`,`project_id`) VALUES ("56","2","Phone Grandfather to ask about the paradox","Added some _notes_.","0","2004-11-28 16:08:33","2004-12-30",NULL,"1");
INSERT INTO `todos` (`id`,`context_id`,`description`,`notes`,`done`,`created`,`due`,`completed`,`project_id`) VALUES ("61","6","Get a book out of the library","Dinosaurs\'R\'Us","0","2004-12-22 14:07:06","0000-00-00",NULL,"3");
INSERT INTO `todos` (`id`,`context_id`,`description`,`notes`,`done`,`created`,`due`,`completed`,`project_id`) VALUES ("60","4","Upgrade to Rails 0.9.1","","1","2004-12-20 17:02:52","2004-12-21","2004-12-20 17:06:48",NULL);
INSERT INTO `todos` (`id`,`context_id`,`description`,`notes`,`done`,`created`,`due`,`completed`,`project_id`) VALUES ("65","1","This should be due today","","0","2004-12-31 17:23:06","2004-12-31",NULL,NULL);
INSERT INTO `todos` (`id`,`context_id`,`description`,`notes`,`done`,`created`,`due`,`completed`,`project_id`) VALUES ("75","1","foo","","1","2004-12-31 18:38:34","2005-01-05","2005-01-02 12:27:10",NULL);
INSERT INTO `todos` (`id`,`context_id`,`description`,`notes`,`done`,`created`,`due`,`completed`,`project_id`) VALUES ("81","1","Buy shares","","0","2005-01-01 12:40:26","2005-02-01",NULL,"2");
INSERT INTO `todos` (`id`,`context_id`,`description`,`notes`,`done`,`created`,`due`,`completed`,`project_id`) VALUES ("85","1","Buy stegosaurus bait","","1","2005-01-01 12:53:12","2005-01-02","2005-01-01 12:53:43","3");
INSERT INTO `todos` (`id`,`context_id`,`description`,`notes`,`done`,`created`,`due`,`completed`,`project_id`) VALUES ("92","1","New action in context","Some notes","1","2005-01-02 14:52:49","2005-03-01","2005-01-02 15:44:19","3");
INSERT INTO `todos` (`id`,`context_id`,`description`,`notes`,`done`,`created`,`due`,`completed`,`project_id`) VALUES ("97","2","Call stock broker","tel: 12345","0","2005-01-03 11:38:25","0000-00-00",NULL,"2");
# Dump of table users
# ------------------------------------------------------------
CREATE TABLE `users` (
`id` int(11) NOT NULL auto_increment,
`login` varchar(80) default NULL,
`password` varchar(40) default NULL,
PRIMARY KEY (`id`)
) TYPE=MyISAM;
INSERT INTO `users` (`id`,`login`,`password`) VALUES ("1","test","9a91e1d8d95b6315991a88121bb0aa9f03ba0dfc");

View file

@ -0,0 +1,34 @@
## Tracks :: GTD web application
## $LastChangedDate$
## $HeadURL$
Main project site: <http://www.rousette.org.uk/projects/>
Project wiki: <http://www.rousette.org.uk/projects/wiki/>
## Version 1.01
A small increment to fix a few bugs and typographical errors in the README:
1. README.txt now lists the correct location for the dump file
2. Fixed the redirection from the login page. Once you have signed up or logged in, you should be taken automatically to the main todo/list page. This also works once you have logged out and clicked the "<< login" page to get back to login/login. (Thanks, Max Prophet!)
3. Properly updated for Rails 0.9.3: this probably means that it won't work for a lower version of Rails. If you have the gems version of Rails installed, you can update it with:
sudo gem update rails
4. Made some minor changes to the appearance of the listed items, so that the description wraps properly, and the tool buttons (edit, delete and notes) are always in the same place relative to the checkbox.
## Version 1.0
1. Updated to run on Rails 0.9.1. This should work with any 0.9.x branch.
2. Added a proper edit page for todos. This also allows you to add a todo to a project, or re-assign it to a new project.
3. Improved the efficiency of the Projects page: it now only finds the Project you've selected, rather than all of them (thanks, Johan <http://theexciter.com/>!)
4. You now get a warning if you try to delete a project or context with undone items. If you choose to continue, the dependent items will be deleted, so that the list page should no longer break.
5. Using Redcloth for markup now that it allows you to use either Textile or Markdown format transparently. This is now included in the distribution, so that you don't need to install it.
6. Added links to context/list page so that you can go directly to todo/show/blah if you click the link for context 'blah'.
7. You can now set the date format you want to use in the file config/settings.yml. Use the strftime formats, with whatever separator you like. e.g. If you want 2004-12-31, the correct format is %Y-%m-%d. 31/12/2004 would be %d/%m/%Y. The same format is used for entry of the date in the due date box, and for display of the date in the list.
8. You can now add a new item to a particular project when you are viewing it at /project/show/[id]. This makes it easy to add a block of next actions to a project. Edit and delete buttons work on this page, but redirect you to /todo/list. I need to fix this.
9. Added a login system by using the login_generator:
<http://wiki.rubyonrails.com/rails/show/LoginGenerator>
The first time you access the system, you need to visit <http://[tracks_url]/login/signup> to enter a username and password. Then when you visit, you will be greeted with a login page. This stores a temporary cookie for your session. The whole app is protected by the login.
10. You can now add a new item to a particular context when you are viewing it at /context/show/[id]. This makes it easy to add a block of next actions to a project. Edit and delete buttons work on this page, but redirect you to /todo/list. I need to fix this.
11. Feeds! There's an RSS feed available at <http://[tracks_url]/feed/na_feed> which shows the last 15 next actions, and a text feed at <http://[tracks_url]/feed/na_text> which gives you a plain text list of all your next actions, sorted by context. You can use the latter to display your next actions on the desktop with GeekTool. Simply set up a shell command containing the following:
curl http://[tracks_url]/feed/na_text
Obviously, you need to replace [tracks_url] with the actual URL to the Tracks application.

40
tracks/doc/README.txt Normal file
View file

@ -0,0 +1,40 @@
Tracks: a GTD web application, built with Ruby on Rails
-------------------------------------------------------------
## $LastChangedDate$
## $HeadURL$
# Homepage:: http://www.rousette.org.uk/projects/
# Author:: bsag (http://www.rousette.org.uk/)
# Version:: 1.01
# Copyright:: (cc) 2004-2005 rousette.org.uk
# License:: GNU GPL
This is a still a work in progress, and there's almost no error checking or validation of the data yet. Use caution when you run it, and make sure that you back up any important data. Full changenotes can be found in tracks/doc/CHANGENOTES.txt. Full API documentation can be found at tracks/doc/app/index.html.
**IF THIS CRASHES YOUR MACHINE AND LOSES YOUR DATA, IT'S NOT MY FAULT!**
## Installation
Before you start, you need to make sure that you have Ruby 1.8.x, mySQL and Rails 0.9.x. Note particularly the last requirement: this will probably not work with Rails 0.8.x. I have now included RedCloth 3.0 (which allows both Textile and Markdown format in the notes field) in the distribution. Find out more about RedCloth here:
<http://www.whytheluckystiff.net/ruby/redcloth/>
It's licensed under a BSD license.
1. Unzip tracks.zip somewhere in your home folder ( e.g. /Users/yourusername/Sites).
2. Make a mySQL database called tracks for which you have full access rights.
3. Import the tables and contents using the tracks_dump 03.01.2005.sql file (in tracks/db). If you have previously used the application, export the contents of the tables from your old todo database and import them into the tracks database.
4. Open the tracks/config/database.yml file, and enter your username and password details.
5. Open the tracks/config/setting.yml file, and enter your desired format for dates (see CHANGENOTES.txt for details).
6. Open Terminal and navigate to the todo folder in your Sites folder.
7. Run the command: ruby script/server --environment=production
If you already have the previous GTD application running, make sure that you stop the server, or run Tracks on a different port with ruby script/server --environment=production --port=3030
8. *IMPORTANT* Tracks now has password protection on all the browser accessible files. The first time that you access it, you need to visit <http://127.0.0.1:3000/login/signup>. Choose your username and password, and you will be directed back to the main listing page (<http://127.0.0.1:3000/todo/list>).
9. Have fun!
## Contacting me
I'd love any suggestions you have for improvements, bug-fixes etc. Email me on:
butshesagirl@rousette.org.uk
You can also leave bug reports, feature requests, and comments at:
<http://www.rousette.org.uk/projects/wiki/>

View file

@ -0,0 +1,87 @@
require_dependency "user"
module LoginSystem
protected
# overwrite this if you want to restrict access to only a few actions
# or if you want to check if the user has the correct rights
# example:
#
# # only allow nonbobs
# def authorize?(user)
# user.login != "bob"
# end
def authorize?(user)
true
end
# overwrite this method if you only want to protect certain actions of the controller
# example:
#
# # don't protect the login and the about method
# def protect?(action)
# if ['action', 'about'].include?(action)
# return false
# else
# return true
# end
# end
def protect?(action)
true
end
# login_required filter. add
#
# before_filter :login_required
#
# if the controller should be under any rights management.
# for finer access control you can overwrite
#
# def authorize?(user)
#
def login_required
if not protect?(action_name)
return true
end
if @session['user'] and authorize?(@session['user'])
return true
end
# store current location so that we can
# come back after the user logged in
store_location
# call overwriteable reaction to unauthorized access
access_denied
return false
end
# overwrite if you want to have special behavior in case the user is not authorized
# to access the current operation.
# the default action is to redirect to the login screen
# example use :
# a popup window might just close itself for instance
def access_denied
redirect_to :controller=>"login", :action =>"login"
end
# store current uri in the session.
# we can return to this location by calling return_location
def store_location
@session['return-to'] = @request.request_uri
end
# move to the last store_location call or to the passed default one
def redirect_back_or_default(default)
if @session['return-to'].nil?
redirect_to default
else
redirect_to_url @session['return-to']
@session['return-to'] = nil
end
end
end

1018
tracks/lib/redcloth.rb Normal file

File diff suppressed because it is too large Load diff

0
tracks/log.tmpl/apache.log Executable file
View file

View file

0
tracks/log.tmpl/production.log Executable file
View file

0
tracks/log.tmpl/test.log Executable file
View file

29
tracks/public/.htaccess Normal file
View file

@ -0,0 +1,29 @@
# General Apache options
AddHandler fastcgi-script .fcgi
AddHandler cgi-script .cgi
Options +FollowSymLinks +ExecCGI
# Make sure that mod_ruby.c has been added and loaded as a module with Apache
RewriteEngine On
# Change extension from .cgi to .fcgi to switch to FCGI and to .rb to switch to mod_ruby
RewriteBase /dispatch.cgi
# Enable this rewrite rule to point to the controller/action that should serve root.
# RewriteRule ^$ /controller/action [R]
# Add missing slash
RewriteRule ^([-_a-zA-Z0-9]+)$ /$1/ [R]
# Default rewriting rules.
RewriteRule ^([-_a-zA-Z0-9]+)/([-_a-zA-Z0-9]+)/([0-9]+)$ ?controller=$1&action=$2&id=$3 [QSA,L]
RewriteRule ^([-_a-zA-Z0-9]+)/([-_a-zA-Z0-9]+)$ ?controller=$1&action=$2 [QSA,L]
RewriteRule ^([-_a-zA-Z0-9]+)/$ ?controller=$1&action=index [QSA,L]
RewriteRule ^([-_a-zA-Z0-9]+)/([-_a-zA-Z0-9]+)/([-_a-zA-Z0-9]+)/([0-9]+)$ ?module=$1&controller=$2&action=$3&id=$4 [QSA,L]
RewriteRule ^([-_a-zA-Z0-9]+)/([-_a-zA-Z0-9]+)/([-_a-zA-Z0-9]+)$ ?module=$1&controller=$2&action=$3 [QSA,L]
RewriteRule ^([-_a-zA-Z0-9]+)/([-_a-zA-Z0-9]+)/$ ?module=$1&controller=$2&action=index [QSA,L]
# You can also point these error messages to a controller/action
ErrorDocument 500 /500.html
ErrorDocument 404 /404.html

6
tracks/public/404.html Normal file
View file

@ -0,0 +1,6 @@
<html>
<body>
<h1>File not found</h1>
<p>Change this error message for pages not found in public/404.html</p>
</body>
</html>

6
tracks/public/500.html Normal file
View file

@ -0,0 +1,6 @@
<html>
<body>
<h1>Application error (Apache)</h1>
<p>Change this error message for exceptions thrown outside of an action (like in Dispatcher setups or broken Ruby code) in public/500.html</p>
</body>
</html>

View file

@ -0,0 +1,70 @@
<html>
<head>
<title>Rails: Welcome on board</title>
<style>
body { background-color: #fff; color: #333; }
body, p, ol, ul, td {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
line-height: 18px;
}
li {
margin-bottom: 7px;
}
pre {
background-color: #eee;
padding: 10px;
font-size: 11px;
}
a { color: #000; }
a:visited { color: #666; }
a:hover { color: #fff; background-color:#000; }
</style>
</head>
<body>
<h1>Congratulations, you've put Ruby on Rails!</h1>
<p><b>Before you move on</b>, verify that the following conditions have been met:</p>
<ol>
<li>The log directory and the empty log files must be writable to the web server (<code>chmod -R 777 log</code>).
<li>
The shebang line in the public/dispatch* files must reference your Ruby installation. <br/>
You might need to change it to <code>#!/usr/bin/env ruby</code> or point directly at the installation.
</li>
<li>
Rails on Apache needs to have the cgi handler and mod_rewrite enabled. <br/>
Somewhere in your httpd.conf, you should have:<br/>
<code>AddHandler cgi-script .cgi</code><br/>
<code>LoadModule rewrite_module libexec/httpd/mod_rewrite.so</code><br/>
<code>AddModule mod_rewrite.c</code>
</li>
</ol>
<p>Take the following steps to get started:</p>
<ol>
<li>Create empty development and test databases for your application.<br/>
<small>Recommendation: Use *_development and *_test names, such as basecamp_development and basecamp_test</small><br/>
<small>Warning: Don't point your test database at your development database, it'll destroy the latter on test runs!</small>
<li>Edit config/database.yml with your database settings.
<li>Create controllers and models using the generator in <code>script/generate</code> <br/>
<small>Help: Run the generator with no arguments for documentation</small>
<li>See all the tests run by running <code>rake</code>.
<li>Develop your Rails application!
<li>Setup Apache with <a href="http://www.fastcgi.com">FastCGI</a> (and <a href="http://raa.ruby-lang.org/list.rhtml?name=fcgi">Ruby bindings</a>), if you need better performance
</ol>
<p>
Having problems getting up and running? First try debugging it yourself by looking at the log files. <br/>
Then try the friendly Rails community <a href="http://www.rubyonrails.org">on the web</a> or <a href="http://www.rubyonrails.org/show/IRC">on IRC</a>
(<a href="irc://irc.freenode.net/#rubyonrails">FreeNode#rubyonrails</a>).
</p>
</body>
</html>

10
tracks/public/dispatch.cgi Executable file
View file

@ -0,0 +1,10 @@
#!/usr/local/bin/ruby
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
require "dispatcher"
ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) }
Dispatcher.dispatch

7
tracks/public/dispatch.fcgi Executable file
View file

@ -0,0 +1,7 @@
#!/usr/local/bin/ruby
require File.dirname(__FILE__) + "/../config/environment"
require 'dispatcher'
require 'fcgi'
FCGI.each_cgi { |cgi| Dispatcher.dispatch(cgi) }

10
tracks/public/dispatch.rb Executable file
View file

@ -0,0 +1,10 @@
#!/usr/local/bin/ruby
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
# If you're using RubyGems and mod_ruby, this require should be changed to an absolute path one, like:
# "/usr/local/lib/ruby/gems/1.8/gems/rails-0.8.0/lib/dispatcher" -- otherwise performance is severely impaired
require "dispatcher"
ADDITIONAL_LOAD_PATHS.reverse.each { |dir| $:.unshift(dir) if File.directory?(dir) }
Dispatcher.dispatch

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 905 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

1
tracks/public/index.html Normal file
View file

@ -0,0 +1 @@
<html><head><META HTTP-EQUIV="Refresh" CONTENT="0;URL=_doc/index.html"></head></html>

View file

@ -0,0 +1,13 @@
function toggleAll(itemname,state)
{
tmp = document.getElementsByTagName('div');
   for (i=0;i<tmp.length;i++)
     {
       if (tmp[i].className == itemname) tmp[i].style.display = state;
     }
}
function toggle(idname)
{
document.getElementById(idname).style.display = (document.getElementById(idname).style.display == 'none') ? 'block' : 'none';
}

View file

@ -0,0 +1,51 @@
body { background-color: #fff; color: #333; }
body, p, ol, ul, td {
font-family: verdana, arial, helvetica, sans-serif;
font-size: 12px;
line-height: 18px;
background: #eee;
}
a { color: #000; }
a:visited { color: #666; }
a:hover { color: #fff; background-color: #000; }
h1, h2, h3 { color: #333; font-family: verdana, arial, helvetica, sans-serif; text-align: center; }
h1 { font-size: 28px }
h2 { font-size: 19px }
h3 { font-size: 16px }
li { margin-bottom: 7px; }
pre {
background-color: #eee;
padding: 10px;
font-size: 11px;
}
#scaffold-main {
width: 80%;
margin: 10px auto;
padding: 6px;
}
div.form {
width: 40%;
margin: 100px auto;
padding: 10px;
border: 1px solid #999;
background: #ff9;
}
div.memo {
width: 40%;
margin: 100px auto;
padding: 10px;
border: 1px solid #999;
background: #ff9;
}
.memo p {
background: #ff9;
}

View file

@ -0,0 +1,251 @@
/* Stylesheet for the main listing page */
body {
font-family: "Lucida Grande", Verdana, Geneva, Arial, sans-serif;
font-size: 12px;
line-height: 19px;
padding: 0px 10px;
margin: 0px;
background: #eee;
}
p {
padding: 2px;
}
a, a:link, a:active, a:visited {
color: #cc3334;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
/* Structural divs */
#display_box {
float: left;
width: 450px;
margin: 0px 15px 50px 15px;
}
#display_box_projects {
float: left;
width: 820px;
margin: 0px 15px 50px 15px;
}
/* Navigation links at the top */
#navcontainer {
margin: 15px;
width: 820px;
}
#navlist {
margin: 0;
padding: 0 0 20px 10px;
border-bottom: 1px solid #000;
}
#navlist ul, #navlist li {
margin: 0;
padding: 0;
display: inline;
list-style-type: none;
}
#navlist a:link, #navlist a:visited {
float: left;
line-height: 14px;
font-weight: bold;
margin: 0 10px 4px 10px;
text-decoration: none;
color: #999;
}
#navlist a:link#current, #navlist a:visited#current, #navlist a:hover {
border-bottom: 4px solid #000;
padding-bottom: 2px;
background: transparent;
color: #000;
}
#navlist a:hover { color: #000; }
.contexts {
padding: 0px 5px 2px 5px;
border: 1px solid #999;
margin: 0px 0px 15px 0px;
background: #fff;
}
.contexts h2 {
background: #CCC;
padding: 5px;
margin-top: 0px;
margin-left: -5px;
margin-right: -5px;
color: #fff;
text-shadow: rgba(0,0,0,.4) 0px 2px 5px;
}
h2 a, h2 a:link, h2 a:active, h2 a:visited {
color: #fff;
text-decoration: none;
}
h2 a:hover {
color: #cc3334;
text-decoration: none;
}
#input_box {
margin: 20px 50px 20px 490px;
padding: 0px 15px 0px 15px;
border: 1px solid #999;
}
#input_box h2 {
background: #CCC;
padding: 5px;
margin-top: 0px;
margin-left: -15px;
margin-right: -15px;
color: #fff;
text-shadow: rgba(0,0,0,.4) 0px 2px 5px;
}
.box {
float: left;
width: 20px;
}
.description {
margin-left: 25px;
margin-right: 10px;
}
.tools {
margin-left: 25px;
width: 40px;
border-top: 1px solid #999;
}
#footer {
width: 820px;
clear: both;
font-size: 0.8em;
text-align: center;
background: #CCC;
border: 1px solid #999;
margin: 0px 10px;
padding: 5px;
}
/* The notes which may be attached to an item */
.notes {
margin: 5px 20px;
padding: 3px;
border: 1px solid #F5ED59;
background: #FAF6AE;
color: #666666;
}
.notes p, .notes li {
padding: 1px 5px;
margin: 0px;
font-size: 12px;
}
.notes ul {
list-style-type: disc;
margin-left: 5px;
}
.notes ol {
list-style-type: decimal;
margin-left: 5px;
}
/* The alert box notifications */
.confirmation {
margin: 20px 50px 20px 490px;
border: 1px solid #007E00;
background-color: #c2ffc2;
padding: 5px;
color: #007E00;
text-align: center;
}
.warning {
margin: 20px 50px 20px 490px;
border: 1px solid #ED2E38;
background-color: #F6979C;
padding: 5px;
color: #007E00;
text-align: center;
}
/* Draw attention to some text
Same format as traffic lights */
.red {
color: #fff;
background: #f00;
padding: 1px;
font-size: 10px;
}
.amber {
color: #fff;
background: #ff6600;
padding: 1px;
font-size: 10px;
}
.green {
color: #fff;
background: #33cc00;
padding: 1px;
font-size: 10px;
}
.grey {
color: #fff;
background: #999;
padding: 1px;
font-size: 10px;
}
/* Shows the number of undone next action */
.badge {
color: #fff;
background: #f00;
padding: 5px;
font-size: 16px;
margin: 10px 10px 0px 0px;
}
ul {
list-style-type: none;
margin-left: -25px;
}
li {
font-size: 1.1em;
padding: 3px 0px;
}
td {
border: 1px solid #999;
}
.even_row {
background: #fff;
}
.odd_row {
background: #cbffff;
}

4
tracks/script/breakpointer Executable file
View file

@ -0,0 +1,4 @@
#!/usr/local/bin/ruby
require 'rubygems'
require_gem 'rails'
require 'breakpoint_client'

30
tracks/script/console Executable file
View file

@ -0,0 +1,30 @@
#!/usr/local/bin/ruby
if ARGV[0]
ENV['RAILS_ENV'] = ARGV[0]
puts "Loading environment..."
exec "irb -r config/environment.rb -r irb/completion --noinspect"
else
puts <<-HELP
NAME
console - interact with the domain model through a environment console (on IRB)
SYNOPSIS
console [environment]
DESCRIPTION
Starts an environment console using IRB that lets you manipulate and interrogate
the domain model or even trigger controller actions. The database connection and
configuration available to the web application is already setup.
Tab completion is available to see classes and methods on individual objects.
EXAMPLE
console production
This will initialize the production environment (as setup in config/database.yml
and config/environments/production.rb). You would now be ready to start requiring
models using require_dependency.
HELP
end

69
tracks/script/generate Executable file
View file

@ -0,0 +1,69 @@
#!/usr/local/bin/ruby
require File.dirname(__FILE__) + '/../config/environment'
require 'rails_generator'
ARGV.shift unless ARGV.empty? or not ['--help', '-h'].include?(ARGV[0])
def find_synonyms(word)
require 'open-uri'
uri = "http://wordnet.princeton.edu/cgi-bin/webwn2.0?stage=2" +
"&word=%s&posnumber=1&searchtypenumber=2&senses=&showglosses=1"
open(uri % word) do |stream|
data = stream.read.gsub("&nbsp;", " ").gsub("<BR>", "")
data.scan(/^Sense \d+\n.+?\n\n/m)
end
rescue Exception
return nil
end
unless ARGV.empty?
begin
name = ARGV.shift
generator = Rails::Generator.instance(name, ARGV)
if msg = generator.collision_with_builtin? then
$stderr.puts msg
if synonyms = find_synonyms(generator.class_name) then
$stderr.puts(
"", "Here are a few synonyms from WordNet. Maybe they will help you find an alternative name.",
"", synonyms
)
end
else
generator.generate
end
rescue Rails::Generator::UsageError => e
puts e.message
end
else
builtin_generators = Rails::Generator.builtin_generators.join(', ')
contrib_generators = Rails::Generator.contrib_generators.join(', ')
$stderr.puts <<end_usage
#{$0} generator [args]
Rails comes with #{builtin_generators} generators.
#{$0} controller Login login logout
#{$0} model Account
#{$0} mailer AccountMailer
#{$0} scaffold Account action another_action
end_usage
unless contrib_generators.empty?
$stderr.puts " Installed generators (in #{RAILS_ROOT}/script/generators):"
$stderr.puts " #{contrib_generators}"
$stderr.puts
end
$stderr.puts <<end_usage
More generators are available at http://rubyonrails.org/show/Generators
1. Download, for example, login_generator.tar.gz
2. Unzip to directory #{RAILS_ROOT}/script/generators/login
3. Generate without args for usage information
#{$0} login
end_usage
exit 0
end

49
tracks/script/server Executable file
View file

@ -0,0 +1,49 @@
#!/usr/local/bin/ruby
require 'webrick'
require 'optparse'
OPTIONS = {
:port => 3000,
:ip => "127.0.0.1",
:environment => "development",
:server_root => File.expand_path(File.dirname(__FILE__) + "/../public/"),
:server_type => WEBrick::SimpleServer
}
ARGV.options do |opts|
script_name = File.basename($0)
opts.banner = "Usage: ruby #{script_name} [options]"
opts.separator ""
opts.on("-p", "--port=port", Integer,
"Runs Rails on the specified port.",
"Default: 3000") { |OPTIONS[:port]| }
opts.on("-b", "--binding=ip", String,
"Binds Rails to the specified ip.",
"Default: 127.0.0.1") { |OPTIONS[:ip]| }
opts.on("-i", "--index=controller", String,
"Specifies an index controller that requests for root will go to (instead of congratulations screen)."
) { |OPTIONS[:index_controller]| }
opts.on("-e", "--environment=name", String,
"Specifies the environment to run this server under (test/development/production).",
"Default: development") { |OPTIONS[:environment]| }
opts.on("-d", "--daemon",
"Make Rails run as a Daemon (only works if fork is available -- meaning on *nix)."
) { OPTIONS[:server_type] = WEBrick::Daemon }
opts.separator ""
opts.on("-h", "--help",
"Show this help message.") { puts opts; exit }
opts.parse!
end
ENV["RAILS_ENV"] = OPTIONS[:environment]
require File.dirname(__FILE__) + "/../config/environment"
require 'webrick_server'
puts "=> Rails application started on http://#{OPTIONS[:ip]}:#{OPTIONS[:port]}"
DispatchServlet.dispatch(OPTIONS)

1
tracks/test/fixtures/contexts.yml vendored Normal file
View file

@ -0,0 +1 @@
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html

1
tracks/test/fixtures/projects.yml vendored Normal file
View file

@ -0,0 +1 @@
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html

1
tracks/test/fixtures/todos.yml vendored Normal file
View file

@ -0,0 +1 @@
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html

1
tracks/test/fixtures/users.yml vendored Normal file
View file

@ -0,0 +1 @@
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html

View file

@ -0,0 +1,17 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'context_controller'
# Re-raise errors caught by the controller.
class ContextController; def rescue_action(e) raise e end; end
class ContextControllerTest < Test::Unit::TestCase
def setup
@controller = ContextController.new
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
end
# Replace this with your real tests.
def test_truth
assert true
end
end

View file

@ -0,0 +1,17 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'feed_controller'
# Re-raise errors caught by the controller.
class FeedController; def rescue_action(e) raise e end; end
class FeedControllerTest < Test::Unit::TestCase
def setup
@controller = FeedController.new
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
end
# Replace this with your real tests.
def test_truth
assert true
end
end

View file

@ -0,0 +1,17 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'login_controller'
# Re-raise errors caught by the controller.
class LoginController; def rescue_action(e) raise e end; end
class LoginControllerTest < Test::Unit::TestCase
def setup
@controller = LoginController.new
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
end
# Replace this with your real tests.
def test_truth
assert true
end
end

View file

@ -0,0 +1,17 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'project_controller'
# Re-raise errors caught by the controller.
class ProjectController; def rescue_action(e) raise e end; end
class ProjectControllerTest < Test::Unit::TestCase
def setup
@controller = ProjectController.new
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
end
# Replace this with your real tests.
def test_truth
assert true
end
end

View file

@ -0,0 +1,17 @@
require File.dirname(__FILE__) + '/../test_helper'
require 'todo_controller'
# Re-raise errors caught by the controller.
class TodoController; def rescue_action(e) raise e end; end
class TodoControllerTest < Test::Unit::TestCase
def setup
@controller = TodoController.new
@request, @response = ActionController::TestRequest.new, ActionController::TestResponse.new
end
# Replace this with your real tests.
def test_truth
assert true
end
end

View file

@ -0,0 +1,14 @@
ENV["RAILS_ENV"] ||= "test"
require File.dirname(__FILE__) + "/../config/environment"
require 'application'
require 'test/unit'
require 'active_record/fixtures'
require 'action_controller/test_process'
require 'breakpoint'
def create_fixtures(*table_names)
Fixtures.create_fixtures(File.dirname(__FILE__) + "/fixtures", table_names)
end
Test::Unit::TestCase.fixture_path = File.dirname(__FILE__) + "/fixtures/"

View file

@ -0,0 +1,10 @@
require File.dirname(__FILE__) + '/../test_helper'
class ContextTest < Test::Unit::TestCase
fixtures :contexts
# Replace this with your real tests.
def test_truth
assert true
end
end

View file

@ -0,0 +1,10 @@
require File.dirname(__FILE__) + '/../test_helper'
class ProjectTest < Test::Unit::TestCase
fixtures :projects
# Replace this with your real tests.
def test_truth
assert true
end
end

View file

@ -0,0 +1,10 @@
require File.dirname(__FILE__) + '/../test_helper'
class TodoTest < Test::Unit::TestCase
fixtures :todos
# Replace this with your real tests.
def test_truth
assert true
end
end

View file

@ -0,0 +1,10 @@
require File.dirname(__FILE__) + '/../test_helper'
class UserTest < Test::Unit::TestCase
fixtures :users
# Replace this with your real tests.
def test_truth
assert true
end
end