├── .gitignore
├── COPYING
├── README
├── Rakefile
├── app
├── controllers
│ ├── application_controller.rb
│ ├── card_controller.rb
│ ├── juggernaut_sync_controller.rb
│ ├── login_controller.rb
│ ├── project_controller.rb
│ └── taskboard_controller.rb
├── helpers
│ ├── application_helper.rb
│ ├── card_helper.rb
│ ├── juggernaut_sync_helper.rb
│ ├── login_helper.rb
│ ├── project_helper.rb
│ └── taskboard_helper.rb
├── models
│ ├── card.rb
│ ├── column.rb
│ ├── hour.rb
│ ├── project.rb
│ ├── row.rb
│ ├── taskboard.rb
│ └── user.rb
└── views
│ ├── login
│ ├── _user_meta.html.erb
│ ├── add_user.html.erb
│ ├── list_users.html.erb
│ └── login.html.erb
│ ├── project
│ ├── _footer.html.erb
│ ├── _project.html.erb
│ └── index.html.erb
│ └── taskboard
│ ├── _taskboard.html.erb
│ └── show.html.erb
├── config
├── boot.rb
├── database.example.yml
├── environment.rb
├── environments
│ ├── development.rb
│ ├── production.rb
│ └── test.rb
├── initializers
│ ├── inflections.rb
│ ├── mime_types.rb
│ ├── new_rails_defaults.rb
│ └── require.rb
├── juggernaut.example.yml
├── juggernaut_hosts.example.yml
├── routes.rb
└── taskboard.example.yml
├── db
├── migrate
│ ├── 20081010142942_create_cards.rb
│ ├── 20081013145250_create_taskboards.rb
│ ├── 20081013170754_create_columns.rb
│ ├── 20081031114623_foreign_keys.rb
│ ├── 20081127152023_acts_as_taggable_migration.rb
│ ├── 20081205134317_create_hours.rb
│ ├── 20090317140555_create_sessions.rb
│ ├── 20090428084605_create_users.rb
│ ├── 20090428123003_add_default_users.rb
│ ├── 20090706124829_create_rows.rb
│ ├── 20090707130233_add_cards_to_rows.rb
│ ├── 20090922095631_create_projects.rb
│ └── 20090922100811_add_taskboards_to_projects.rb
└── schema.rb
├── lib
├── jira_integration.rb
├── jira_parser.rb
├── migration_helpers.rb
├── taskboard_config.rb
├── taskboard_version.rb
├── url_parser.rb
└── utils.rb
├── log
└── report
│ └── readme
├── public
├── 404.html
├── 422.html
├── 500.html
├── dispatch.cgi
├── dispatch.fcgi
├── dispatch.rb
├── favicon.ico
├── favicon.png
├── images
│ ├── cognifide_logo.png
│ ├── collapse_all.png
│ ├── color_big_off.png
│ ├── color_big_on.png
│ ├── color_off.png
│ ├── color_on.png
│ ├── copy.png
│ ├── cross_16.png
│ ├── cross_off.png
│ ├── cross_on.png
│ ├── expand_all.png
│ ├── hide_off.png
│ ├── hide_on.png
│ ├── jquery
│ │ └── jquery.colorpicker.gif
│ ├── loading.gif
│ ├── logo.png
│ ├── open_off.png
│ ├── open_on.png
│ ├── plus.png
│ ├── rails.png
│ ├── remove_cards_off.png
│ ├── remove_cards_on.png
│ ├── rename.png
│ ├── section_closed.png
│ ├── section_opened.png
│ ├── taskboard.png
│ ├── taskboard_clone.png
│ ├── taskboard_plus.png
│ ├── tip-left.png
│ ├── tip-top.png
│ ├── tip.png
│ └── warning.png
├── javascripts
│ ├── footer.js
│ ├── home.js
│ ├── juggernaut
│ │ ├── juggernaut.js
│ │ └── swfobject.js
│ ├── lib
│ │ ├── excanvas.compiled.js
│ │ ├── jqUnit.js
│ │ ├── jquery-ui.min.js
│ │ ├── jquery.colorpicker.js
│ │ ├── jquery.cookie.js
│ │ ├── jquery.flot.js
│ │ ├── jquery.jeditable.js
│ │ ├── jquery.js
│ │ ├── jrails.js
│ │ ├── juggernaut
│ │ │ ├── jquerynaut.js
│ │ │ ├── json.js
│ │ │ ├── juggernaut.js
│ │ │ └── swfobject.js
│ │ └── showdown.js
│ ├── taskboard.js
│ └── utils.js
├── juggernaut
│ ├── expressinstall.swf
│ └── juggernaut.swf
├── robots.txt
└── stylesheets
│ ├── generic.css
│ ├── home.css
│ ├── login.css
│ ├── print.css
│ ├── taskboard.css
│ └── testsuite.css
├── script
├── about
├── autospec
├── console
├── dbconsole
├── destroy
├── generate
├── performance
│ ├── benchmarker
│ ├── profiler
│ └── request
├── plugin
├── process
│ ├── inspector
│ ├── reaper
│ └── spawner
├── runner
├── server
└── spin
├── spec
├── controllers
│ ├── card_controller_spec.rb
│ ├── juggernaut_sync_controller_spec.rb
│ ├── login_controller_spec.rb
│ ├── project_controller_spec.rb
│ └── taskboard_controller_spec.rb
├── fixtures
│ ├── cards.yml
│ ├── columns.yml
│ ├── hours.yml
│ ├── jira-filter-01.xml
│ ├── jira-issue-01.xml
│ ├── projects.yml
│ ├── rows.yml
│ ├── taggings.yml
│ ├── tags.yml
│ ├── taskboards.yml
│ └── users.yml
├── helpers
│ ├── application_helper_spec.rb
│ ├── card_helper_spec.rb
│ ├── login_helper_spec.rb
│ ├── project_helper_spec.rb
│ └── taskboard_helper_spec.rb
├── javascripts
│ ├── fixtures
│ │ ├── home.html
│ │ ├── screw.css
│ │ └── utils.html
│ ├── home_spec.js
│ ├── spec_helper.js
│ └── utils_spec.js
├── lib
│ ├── jira_integration_spec.rb
│ ├── jira_parser_spec.rb
│ ├── taskboard_config_spec.rb
│ ├── taskboard_version_spec.rb
│ ├── url_parser_spec.rb
│ └── utils_spec.rb
├── models
│ ├── card_spec.rb
│ ├── column_spec.rb
│ ├── hour_spec.rb
│ ├── project_spec.rb
│ ├── row_spec.rb
│ ├── taskboard_spec.rb
│ └── user_spec.rb
└── spec_helper.rb
└── vendor
└── plugins
├── acts_as_list
├── README
├── init.rb
└── lib
│ └── active_record
│ └── acts
│ └── list.rb
├── acts_as_taggable_on_steroids
├── CHANGELOG
├── MIT-LICENSE
├── README
├── Rakefile
├── generators
│ └── acts_as_taggable_migration
│ │ ├── acts_as_taggable_migration_generator.rb
│ │ └── templates
│ │ └── migration.rb
├── init.rb
└── lib
│ ├── acts_as_taggable.rb
│ ├── tag.rb
│ ├── tag_counts_extension.rb
│ ├── tag_list.rb
│ ├── tagging.rb
│ └── tags_helper.rb
├── blue-ridge
├── LICENSE
├── LICENSE-Screw.Unit
├── LICENSE-Smoke
├── README.markdown
├── Rakefile
├── TODO.taskpaper
├── generators
│ ├── blue_ridge
│ │ ├── blue_ridge_generator.rb
│ │ └── templates
│ │ │ ├── application.html
│ │ │ ├── application_spec.js
│ │ │ ├── screw.css
│ │ │ └── spec_helper.js
│ └── javascript_spec
│ │ ├── javascript_spec_generator.rb
│ │ └── templates
│ │ ├── fixture.html.erb
│ │ └── javascript_spec.js.erb
├── lib
│ ├── blue-ridge.js
│ ├── blue_ridge.rb
│ ├── consoleReportForRake.js
│ ├── env.rhino.js
│ ├── jquery-1.2.6.js
│ ├── jquery-1.3.2.js
│ ├── jquery.fn.js
│ ├── jquery.print.js
│ ├── js.jar
│ ├── screw.behaviors.js
│ ├── screw.builder.js
│ ├── screw.events.js
│ ├── screw.matchers.js
│ ├── screw.mocking.js
│ ├── screw.smok.js
│ ├── shell.js
│ ├── smok.js
│ ├── smoke.core.js
│ ├── smoke.mock.js
│ ├── smoke.stub.js
│ └── test_runner.js
├── spec
│ ├── javascripts
│ │ ├── fixtures
│ │ │ ├── screw.behaviors.html
│ │ │ ├── screw.matchers.html
│ │ │ ├── screw.print.html
│ │ │ ├── smoke.core.html
│ │ │ ├── smoke.mock.html
│ │ │ ├── smoke.screw_integration.html
│ │ │ └── smoke.stub.html
│ │ ├── screw.behaviors_spec.js
│ │ ├── screw.matchers_spec.js
│ │ ├── screw.print_spec.js
│ │ ├── smoke.core_spec.js
│ │ ├── smoke.mock_spec.js
│ │ ├── smoke.screw_integration_spec.js
│ │ ├── smoke.stub_spec.js
│ │ └── spec_helper.js
│ └── rubies
│ │ ├── blue_ridge_spec.rb
│ │ └── spec_helper.rb
└── tasks
│ └── javascript_testing_tasks.rake
└── juggernaut_plugin
├── LICENSE
├── README
├── init.rb
├── install.rb
├── lib
├── juggernaut.rb
└── juggernaut_helper.rb
├── media
├── expressinstall.swf
├── jquery.js
├── jquerynaut.js
├── json.js
├── juggernaut.as
├── juggernaut.js
├── juggernaut.swf
├── juggernaut.yml
├── juggernaut_hosts.yml
├── log
│ └── juggernaut.log
└── swfobject.js
└── tasks
└── juggernaut.rake
/.gitignore:
--------------------------------------------------------------------------------
1 | Capfile
2 |
3 | # ignore config files but leave examples
4 | config/deploy.rb
5 | config/*.yml
6 | !config/*.example.yml
7 |
8 | coverage/
9 |
10 | log/*.log
11 | log/*/*.log
12 |
13 | nbproject/
14 | .idea/
15 | .generators
16 |
17 | lib/tasks/cruise.rake
18 | lib/tasks/rspec.rake
19 |
20 | script/spec
21 | script/spec_server
22 |
23 | spec/rcov.opts
24 | spec/spec.opts
25 |
26 | test/
27 | tmp/
28 | taskboard_internal/
29 |
30 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | Taskboard
2 | =========
3 | your on-line tool for task management fun
4 |
5 | http://taskboard.cognifide.com
6 |
7 | Copyright (c) 2008-2009 Cognifide
8 | http://www.cognifide.com
9 |
10 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require(File.join(File.dirname(__FILE__), 'config', 'boot'))
5 |
6 | require 'rake'
7 | require 'rake/testtask'
8 | require 'rake/rdoctask'
9 |
10 | require 'tasks/rails'
11 |
--------------------------------------------------------------------------------
/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | class ApplicationController < ActionController::Base
19 | helper :all # include all helpers, all the time
20 |
21 | before_filter :authorize, :authorize_read_only
22 |
23 | # See ActionController::RequestForgeryProtection for details
24 | # Uncomment the :secret if you're not using the cookie session store
25 | protect_from_forgery # :secret => 'fba8a476189fb5d6dc6a7b9e889fb10f'
26 |
27 | # See ActionController::Base for details
28 | # Uncomment this to filter the contents of submitted sensitive data parameters
29 | # from your application log (in this case, all fields with names like "password").
30 | # filter_parameter_logging :password
31 |
32 | def report_logger(id)
33 | @report_loggers = {} unless @report_loggers
34 | return @report_loggers[id] if @report_loggers[id]
35 | report_file_path = "#{RAILS_ROOT}/log/report/taskboard_#{id}.log"
36 | report_file = File.open(report_file_path, 'a')
37 | report_file.sync = true
38 | @report_loggers[id] = Logger.new(report_file)
39 | end
40 |
41 | private
42 | def authorize
43 | session[:original_uri] = request.request_uri unless request.xhr?
44 | if session[:user_id].nil?
45 | redirect_to(:controller => 'login', :action => 'login')
46 | end
47 | end
48 |
49 | def authorize_read_only
50 | session[:original_uri] = request.request_uri unless request.xhr?
51 | unless session[:user_id].nil?
52 | unless session[:editor]
53 | flash[:notice] = "You do not have permission to do that!"
54 | redirect_to(:controller => 'taskboard', :action => 'index')
55 | end
56 | end
57 | end
58 | end
59 |
--------------------------------------------------------------------------------
/app/controllers/login_controller.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | class LoginController < ApplicationController
19 | before_filter [:authorize, :authorize_read_only], :except => ["login","logout"]
20 |
21 | def add_user
22 | @user = User.new(params[:user])
23 | if request.post? and @user.save
24 | role = @user.editor? ? 'editor' : 'viewer'
25 | flash.now[:notice] = "Added new #{role} user #{@user.username}"
26 | @user = User.new
27 | end
28 | end
29 |
30 | def list_users
31 | @all_users = User.find(:all)
32 | end
33 |
34 | def login
35 | login = params[:login]
36 | password = params[:password]
37 |
38 | if request.post?
39 | if(login.blank? || password.blank?)
40 | flash.now[:notice] = "Please fill in both user name and password!"
41 | else
42 | clear_session
43 | user = User.authenticate(login, password)
44 | if user
45 | session[:user_id] = user.id
46 | session[:user] = user
47 | session[:editor] = user.editor?
48 | uri = session[:original_uri]
49 | session[:original_uri] = nil
50 | redirect_to(uri || {:controller => 'taskboard', :action => "index"})
51 | else
52 | flash.now[:notice] = "Wrong user name or password!"
53 | end
54 | end
55 | end
56 | end
57 |
58 | def logout
59 | clear_session
60 | flash[:notice] = "You have logged out successfuly!";
61 | redirect_to :controller => "login", :action => "login"
62 | end
63 |
64 | private
65 |
66 | def clear_session
67 | session[:user_id] = nil
68 | session[:user] = nil
69 | session[:editor] = false
70 | end
71 | end
72 |
--------------------------------------------------------------------------------
/app/controllers/project_controller.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | class ProjectController < ApplicationController
19 |
20 | before_filter :authorize_read_only, :except => ["index"]
21 |
22 | def index
23 | @projects = Project.find(:all, :order => "name")
24 | end
25 |
26 | def add
27 | project = Project.new
28 | project.name = params[:name].blank? ? Project::DEFAULT_NAME : params[:name]
29 | project.save!
30 | redirect_to :action => 'index'
31 | end
32 |
33 | def rename
34 | project = Project.find(params[:id].to_i)
35 | if not params[:name].blank?
36 | project.name = params[:name]
37 | project.save!
38 | render :json => { :status => 'success', :message => project.name }
39 | else
40 | render :json => { :status => 'error', :message => "Project's name cannot be empty" }
41 | end
42 | end
43 |
44 | end
45 |
--------------------------------------------------------------------------------
/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | # Methods added to this helper will be available to all templates in the application.
19 | module ApplicationHelper
20 |
21 | # just wrap and produce js like data structure
22 | def burndown burndown_aware
23 | data = burndown_aware.burndown.sort.to_a.map{ |x|
24 | # split string so we can get seconds from the epoch (as flot wants us to do)
25 | [ make_time( x[0] ) * 1000, x[1] ]
26 | }
27 | data.inspect
28 | end
29 |
30 | def make_time(time_in_string)
31 | time = time_in_string.split("-")
32 | Time.mktime(time[0], time[1], time[2], 0, 0, 0, 0).to_i
33 | end
34 |
35 | end
36 |
--------------------------------------------------------------------------------
/app/helpers/card_helper.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | module CardHelper
19 | end
20 |
--------------------------------------------------------------------------------
/app/helpers/juggernaut_sync_helper.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | module JuggernautSyncHelper
19 | end
20 |
--------------------------------------------------------------------------------
/app/helpers/login_helper.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | module LoginHelper
19 | end
20 |
--------------------------------------------------------------------------------
/app/helpers/project_helper.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | module ProjectHelper
19 | end
20 |
--------------------------------------------------------------------------------
/app/helpers/taskboard_helper.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | module TaskboardHelper
19 | end
20 |
--------------------------------------------------------------------------------
/app/models/column.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | class Column < ActiveRecord::Base
19 | belongs_to :taskboard
20 |
21 | has_many :cards do
22 | def in_row(row)
23 | find(:all, :conditions => ["row_id = ?", row.id], :order => "position")
24 | end
25 | end
26 |
27 | acts_as_list :scope => :taskboard
28 |
29 | DEFAULT_NAME = 'Brave new column'
30 |
31 | def clone taskboard_id = taskboard_id
32 | Column.new(:name => name, :position => position, :taskboard_id => taskboard_id)
33 | end
34 |
35 | def to_json options = {}
36 | options[:include] = { :cards => { :methods => [:tag_list, :hours_left, :hours_left_updated] }}
37 | options[:except] = [:created_at, :updated_at, :taskboard_id]
38 | super(options)
39 | end
40 |
41 | end
42 |
--------------------------------------------------------------------------------
/app/models/hour.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | class Hour < ActiveRecord::Base
19 | belongs_to :card
20 | end
21 |
--------------------------------------------------------------------------------
/app/models/project.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | class Project < ActiveRecord::Base
19 |
20 | validates_presence_of :name
21 |
22 | has_many :taskboards
23 |
24 | DEFAULT_NAME = "Brand new project"
25 |
26 | end
27 |
--------------------------------------------------------------------------------
/app/models/row.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | class Row < ActiveRecord::Base
19 | belongs_to :taskboard
20 |
21 | has_many :cards do
22 | def in_column(column)
23 | find(:all, :conditions => ["column_id = ?", column.id], :order => "position")
24 | end
25 | end
26 |
27 | acts_as_list :scope => :taskboard
28 |
29 | DEFAULT_NAME = 'Brave new row'
30 |
31 | def clone taskboard_id = taskboard_id
32 | Row.new(:name => name, :position => position, :taskboard_id => taskboard_id)
33 | end
34 |
35 | end
36 |
--------------------------------------------------------------------------------
/app/models/taskboard.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | class Taskboard < ActiveRecord::Base
19 |
20 | validates_presence_of :name
21 |
22 | belongs_to :project
23 |
24 | has_many :cards
25 | has_many :columns, :order => "position"
26 | has_many :rows, :order => "position"
27 |
28 | DEFAULT_NAME = "Brand new taskboard"
29 |
30 | def clone
31 | clonned_taskboard = Taskboard.new(:name => name, :project => project)
32 |
33 | columns_map = {}
34 | rows_map = {}
35 |
36 | columns.sort{|col1, col2| col1.position <=> col2.position}.each { |column|
37 | clonned_column = column.clone
38 | clonned_taskboard.columns << clonned_column
39 | columns_map[column.id] = clonned_column
40 | }
41 |
42 | rows.sort{|row1, row2| row1.position <=> row2.position}.each { |row|
43 | clonned_row = row.clone
44 | clonned_taskboard.rows << clonned_row
45 | rows_map[row.id] = clonned_row
46 | }
47 |
48 | clonned_taskboard.save!
49 |
50 | cards.sort{|c1, c2| c1.position <=> c2.position}.each { |card|
51 | clonned_card = card.clone clonned_taskboard.id, columns_map[card.column_id].id, rows_map[card.row_id].id
52 | clonned_card.save!
53 | }
54 |
55 | clonned_taskboard
56 | end
57 |
58 | def burndown
59 | burndown = Hash.new(0)
60 | self.cards.each { |card|
61 | card.burndown.each_pair { |date, hours|
62 | burndown[date] += hours
63 | }
64 | }
65 |
66 | return burndown
67 | end
68 |
69 | def to_json options = {}
70 | options[:include] = { :columns => {}, :rows => {}, :cards => { :methods => [:tag_list, :hours_left, :hours_left_updated] } }
71 | options[:except] = [:created_at, :updated_at]
72 | super(options)
73 | end
74 | end
75 |
--------------------------------------------------------------------------------
/app/models/user.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | class User < ActiveRecord::Base
19 | validates_presence_of :username
20 | validates_uniqueness_of :username
21 |
22 | attr_accessor :password_confirmation
23 | validates_confirmation_of :password
24 |
25 | def validate
26 | errors.add_to_base("No password") if hashed_password.blank?
27 | end
28 |
29 | def password=(pwd)
30 | @password = pwd
31 | create_new_salt
32 | self.hashed_password = User.encrypted_password(self.password, self.salt)
33 | end
34 |
35 | def password
36 | @password
37 | end
38 |
39 | def self.authenticate(username, password)
40 | user = self.find_by_username(username)
41 | if user
42 | expected_password = encrypted_password(password, user.salt)
43 | user = nil if user.hashed_password != expected_password
44 | end
45 | user
46 | end
47 |
48 | private
49 |
50 | def create_new_salt
51 | self.salt = self.object_id.to_s + rand.to_s
52 | end
53 |
54 | def self.encrypted_password(password, salt)
55 | string_to_hash = password + "taskboard".reverse + salt
56 | Digest::SHA1.hexdigest(string_to_hash)
57 | end
58 |
59 | end
60 |
--------------------------------------------------------------------------------
/app/views/login/_user_meta.html.erb:
--------------------------------------------------------------------------------
1 | <%#
2 | Copyright (C) 2009 Cognifide
3 |
4 | This file is part of Taskboard.
5 |
6 | Taskboard is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Taskboard is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with Taskboard. If not, see .
18 | -%>
19 | <%= session[:user].username %> - <%= link_to "Logout", { :controller => "login", :action => "logout" }, :title => "Logout from Taskboard app" %>
20 |
--------------------------------------------------------------------------------
/app/views/login/add_user.html.erb:
--------------------------------------------------------------------------------
1 | <%#
2 | Copyright (C) 2009 Cognifide
3 |
4 | This file is part of Taskboard.
5 |
6 | Taskboard is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Taskboard is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with Taskboard. If not, see .
18 | -%>
19 |
21 |
22 |
32 | <% end -%>
33 | <%= error_messages_for 'user' %>
34 | <% form_for :user do |form| %>
35 |
48 | <% end %>
49 |
50 |
51 |
--------------------------------------------------------------------------------
/app/views/login/list_users.html.erb:
--------------------------------------------------------------------------------
1 | <%#
2 | Copyright (C) 2009 Cognifide
3 |
4 | This file is part of Taskboard.
5 |
6 | Taskboard is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Taskboard is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with Taskboard. If not, see .
18 | -%>
19 |
21 |
22 |
23 |
24 | Taskboard: login page
25 | <%= stylesheet_link_tag 'login' %>
26 |
27 |
28 |
<%= h(user.username) %><% if user.editor %> - editor<% end %>
33 | <% end -%>
34 |
35 |
36 |
37 |
--------------------------------------------------------------------------------
/app/views/login/login.html.erb:
--------------------------------------------------------------------------------
1 | <%#
2 | Copyright (C) 2009 Cognifide
3 |
4 | This file is part of Taskboard.
5 |
6 | Taskboard is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Taskboard is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with Taskboard. If not, see .
18 | -%>
19 |
21 |
22 |
23 |
24 | Taskboard: login page
25 | <%= stylesheet_link_tag 'login' %>
26 | <%= javascript_include_tag 'lib/jquery', 'lib/jquery-ui.min', 'utils', 'footer' %>
27 |
28 |
29 |
Taskboard
30 |
31 | <% if flash[:notice] -%>
32 |
<%= flash[:notice] %>
33 | <% end -%>
34 | <% form_tag do %>
35 |
44 | <% end %>
45 |
46 | <%= render :partial => 'project/footer' %>
47 |
48 |
49 |
--------------------------------------------------------------------------------
/app/views/project/_footer.html.erb:
--------------------------------------------------------------------------------
1 |
13 |
14 |
--------------------------------------------------------------------------------
/app/views/project/_project.html.erb:
--------------------------------------------------------------------------------
1 | <%#
2 | Copyright (C) 2009 Cognifide
3 |
4 | This file is part of Taskboard.
5 |
6 | Taskboard is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Taskboard is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with Taskboard. If not, see .
18 | -%>
19 |
39 | <% end %>
40 | <% if session[:editor] -%>
41 |
42 |
52 |
53 | <% end -%>
54 |
55 |
56 |
--------------------------------------------------------------------------------
/app/views/project/index.html.erb:
--------------------------------------------------------------------------------
1 | <%#
2 | Copyright (C) 2009 Cognifide
3 |
4 | This file is part of Taskboard.
5 |
6 | Taskboard is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Taskboard is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with Taskboard. If not, see .
18 | -%>
19 |
21 |
22 |
23 | Taskboards
24 | <%= stylesheet_link_tag 'home' %>
25 | <%= javascript_include_tag 'lib/jquery', 'lib/jquery-ui.min', 'utils', 'home', 'lib/jquery.jeditable', 'footer' %>
26 |
31 |
32 |
33 |
34 |
35 |
62 | <%= render :partial => 'footer' %>
63 |
64 |
65 |
--------------------------------------------------------------------------------
/app/views/taskboard/_taskboard.html.erb:
--------------------------------------------------------------------------------
1 | <%#
2 | Copyright (C) 2009 Cognifide
3 |
4 | This file is part of Taskboard.
5 |
6 | Taskboard is free software: you can redistribute it and/or modify
7 | it under the terms of the GNU General Public License as published by
8 | the Free Software Foundation, either version 3 of the License, or
9 | (at your option) any later version.
10 |
11 | Taskboard is distributed in the hope that it will be useful,
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | GNU General Public License for more details.
15 |
16 | You should have received a copy of the GNU General Public License
17 | along with Taskboard. If not, see .
18 | -%>
19 |
25 | <% link_to({ :controller => 'taskboard', :action => 'clone_taskboard', :id => taskboard }, :title => "Create a copy of '#{h(taskboard.name)}'", :rel => 'clone', :class => 'cloneTaskboard') do -%>
26 |
27 | <% end -%>
28 |
29 |
30 | <% end -%>
31 |
32 |
--------------------------------------------------------------------------------
/config/boot.rb:
--------------------------------------------------------------------------------
1 | # Don't change this file!
2 | # Configure your app in config/environment.rb and config/environments/*.rb
3 |
4 | RAILS_ROOT = "#{File.dirname(__FILE__)}/.." unless defined?(RAILS_ROOT)
5 |
6 | module Rails
7 | class << self
8 | def boot!
9 | unless booted?
10 | preinitialize
11 | pick_boot.run
12 | end
13 | end
14 |
15 | def booted?
16 | defined? Rails::Initializer
17 | end
18 |
19 | def pick_boot
20 | (vendor_rails? ? VendorBoot : GemBoot).new
21 | end
22 |
23 | def vendor_rails?
24 | File.exist?("#{RAILS_ROOT}/vendor/rails")
25 | end
26 |
27 | def preinitialize
28 | load(preinitializer_path) if File.exist?(preinitializer_path)
29 | end
30 |
31 | def preinitializer_path
32 | "#{RAILS_ROOT}/config/preinitializer.rb"
33 | end
34 | end
35 |
36 | class Boot
37 | def run
38 | load_initializer
39 | Rails::Initializer.run(:set_load_path)
40 | end
41 | end
42 |
43 | class VendorBoot < Boot
44 | def load_initializer
45 | require "#{RAILS_ROOT}/vendor/rails/railties/lib/initializer"
46 | Rails::Initializer.run(:install_gem_spec_stubs)
47 | Rails::GemDependency.add_frozen_gem_path
48 | end
49 | end
50 |
51 | class GemBoot < Boot
52 | def load_initializer
53 | self.class.load_rubygems
54 | load_rails_gem
55 | require 'initializer'
56 | end
57 |
58 | def load_rails_gem
59 | if version = self.class.gem_version
60 | gem 'rails', version
61 | else
62 | gem 'rails'
63 | end
64 | rescue Gem::LoadError => load_error
65 | $stderr.puts %(Missing the Rails #{version} gem. Please `gem install -v=#{version} rails`, update your RAILS_GEM_VERSION setting in config/environment.rb for the Rails version you do have installed, or comment out RAILS_GEM_VERSION to use the latest version installed.)
66 | exit 1
67 | end
68 |
69 | class << self
70 | def rubygems_version
71 | Gem::RubyGemsVersion rescue nil
72 | end
73 |
74 | def gem_version
75 | if defined? RAILS_GEM_VERSION
76 | RAILS_GEM_VERSION
77 | elsif ENV.include?('RAILS_GEM_VERSION')
78 | ENV['RAILS_GEM_VERSION']
79 | else
80 | parse_gem_version(read_environment_rb)
81 | end
82 | end
83 |
84 | def load_rubygems
85 | min_version = '1.3.2'
86 | require 'rubygems'
87 | unless rubygems_version >= min_version
88 | $stderr.puts %Q(Rails requires RubyGems >= #{min_version} (you have #{rubygems_version}). Please `gem update --system` and try again.)
89 | exit 1
90 | end
91 |
92 | rescue LoadError
93 | $stderr.puts %Q(Rails requires RubyGems >= #{min_version}. Please install RubyGems and try again: http://rubygems.rubyforge.org)
94 | exit 1
95 | end
96 |
97 | def parse_gem_version(text)
98 | $1 if text =~ /^[^#]*RAILS_GEM_VERSION\s*=\s*["']([!~<>=]*\s*[\d.]+)["']/
99 | end
100 |
101 | private
102 | def read_environment_rb
103 | File.read("#{RAILS_ROOT}/config/environment.rb")
104 | end
105 | end
106 | end
107 | end
108 |
109 | # All that for this:
110 | Rails.boot!
111 |
--------------------------------------------------------------------------------
/config/database.example.yml:
--------------------------------------------------------------------------------
1 | development:
2 | host: localhost
3 | adapter: mysql
4 | database: taskboard_development
5 | port: 3306
6 | username: root
7 | password:
8 | encoding: utf8
9 |
10 | # Warning: The database defined as 'test' will be erased and
11 | # re-generated from your development database when you run 'rake'.
12 | # Do not set this db to the same as development or production.
13 | test:
14 | host: localhost
15 | adapter: mysql
16 | database: taskboard_test
17 | port: 3306
18 | username: root
19 | password:
20 | encoding: utf8
21 |
22 | production:
23 | host: localhost
24 | adapter: mysql
25 | database: taskboard_production
26 | port: 3306
27 | username: root
28 | password:
29 | encoding: utf8
30 |
--------------------------------------------------------------------------------
/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file
2 |
3 | # Uncomment below to force Rails into production mode when
4 | # you don't control web/app server and can't set it the proper way
5 | # ENV['RAILS_ENV'] ||= 'production'
6 |
7 | # Specifies gem version of Rails to use when vendor/rails is not present
8 | RAILS_GEM_VERSION = '2.3.5' unless defined? RAILS_GEM_VERSION
9 |
10 | # Bootstrap the Rails environment, frameworks, and default configuration
11 | require File.join(File.dirname(__FILE__), 'boot')
12 |
13 | Rails::Initializer.run do |config|
14 | # Settings in config/environments/* take precedence over those specified here.
15 | # Application configuration should go into files in config/initializers
16 | # -- all .rb files in that directory are automatically loaded.
17 | # See Rails::Configuration for more options.
18 |
19 | # Skip frameworks you're not going to use. To use Rails without a database
20 | # you must remove the Active Record framework.
21 | # config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
22 |
23 | # Specify gems that this application depends on.
24 | # They can then be installed with "rake gems:install" on new installations.
25 | # config.gem "bj"
26 | # config.gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net"
27 | # config.gem "aws-s3", :lib => "aws/s3"
28 |
29 | config.gem "juggernaut"
30 |
31 | # Only load the plugins named here, in the order given. By default, all plugins
32 | # in vendor/plugins are loaded in alphabetical order.
33 | # :all can be used as a placeholder for all plugins not explicitly named
34 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
35 |
36 | # Add additional load paths for your own custom dirs
37 | # config.load_paths += %W( #{RAILS_ROOT}/extras )
38 |
39 | # Force all environments to use the same logger level
40 | # (by default production uses :info, the others :debug)
41 | # config.log_level = :debug
42 |
43 | # Make Time.zone default to the specified zone, and make Active Record store time values
44 | # in the database in UTC, and return them converted to the specified local zone.
45 | # Run "rake -D time" for a list of tasks for finding time zone names. Comment line to use default local time.
46 | config.time_zone = 'UTC'
47 |
48 | # Your secret key for verifying cookie session data integrity.
49 | # If you change this key, all old sessions will become invalid!
50 | # Make sure the secret is at least 30 characters and all random,
51 | # no regular words or you'll be exposed to dictionary attacks.
52 | config.action_controller.session = {
53 | :session_key => '_taskboard_session',
54 | :secret => '3e5780da30892c424c7fb051c8cd8bc97cdb312c00b0cfb8a476c8958d1fdbcd201859f92eb2716487d0ab1665e0a56f002de854d38cc121e849480bb49d95c8'
55 | }
56 |
57 | # Use the database for sessions instead of the cookie-based default,
58 | # which shouldn't be used to store highly confidential information
59 | # (create the session table with "rake db:sessions:create")
60 | config.action_controller.session_store = :active_record_store
61 |
62 | # Use SQL instead of Active Record's schema dumper when creating the test database.
63 | # This is necessary if your schema can't be completely dumped by the schema dumper,
64 | # like if you have constraints or database-specific column types
65 | # config.active_record.schema_format = :sql
66 |
67 | # Activate observers that should always be running
68 | # config.active_record.observers = :cacher, :garbage_collector
69 |
70 |
71 |
72 | end
73 |
--------------------------------------------------------------------------------
/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | # Settings specified here will take precedence over those in config/environment.rb
2 |
3 | # In the development environment your application's code is reloaded on
4 | # every request. This slows down response time but is perfect for development
5 | # since you don't have to restart the webserver when you make code changes.
6 | config.cache_classes = false
7 |
8 | # Log error messages when you accidentally call methods on nil.
9 | config.whiny_nils = true
10 |
11 | # Show full error reports and disable caching
12 | config.action_controller.consider_all_requests_local = true
13 | config.action_view.debug_rjs = true
14 | config.action_controller.perform_caching = false
15 |
16 | # Don't care if the mailer can't send
17 | config.action_mailer.raise_delivery_errors = false
18 |
--------------------------------------------------------------------------------
/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | # Settings specified here will take precedence over those in config/environment.rb
2 |
3 | # The production environment is meant for finished, "live" apps.
4 | # Code is not reloaded between requests
5 | config.cache_classes = true
6 |
7 | # Use a different logger for distributed setups
8 | # config.logger = SyslogLogger.new
9 |
10 | # Full error reports are disabled and caching is turned on
11 | config.action_controller.consider_all_requests_local = false
12 | config.action_controller.perform_caching = true
13 | config.action_view.cache_template_loading = true
14 |
15 | # Use a different cache store in production
16 | # config.cache_store = :mem_cache_store
17 |
18 | # Enable serving of images, stylesheets, and javascripts from an asset server
19 | # config.action_controller.asset_host = "http://assets.example.com"
20 |
21 | # Disable delivery errors, bad email addresses will be ignored
22 | # config.action_mailer.raise_delivery_errors = false
23 |
--------------------------------------------------------------------------------
/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | # Settings specified here will take precedence over those in config/environment.rb
2 |
3 | # The test environment is used exclusively to run your application's
4 | # test suite. You never need to work with it otherwise. Remember that
5 | # your test database is "scratch space" for the test suite and is wiped
6 | # and recreated between test runs. Don't rely on the data there!
7 | config.cache_classes = true
8 |
9 | # Log error messages when you accidentally call methods on nil.
10 | config.whiny_nils = true
11 |
12 | # Show full error reports and disable caching
13 | config.action_controller.consider_all_requests_local = true
14 | config.action_controller.perform_caching = false
15 |
16 | # Disable request forgery protection in test environment
17 | config.action_controller.allow_forgery_protection = false
18 |
19 | # Tell Action Mailer not to deliver emails to the real world.
20 | # The :test delivery method accumulates sent emails in the
21 | # ActionMailer::Base.deliveries array.
22 | config.action_mailer.delivery_method = :test
23 |
24 | config.gem 'rspec', :lib => 'spec'
25 | config.gem 'rspec-rails', :lib => 'spec'
26 | config.gem 'ZenTest', :lib => false
27 | config.gem 'rcov', :lib => false
28 |
--------------------------------------------------------------------------------
/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format
4 | # (all these examples are active by default):
5 | # ActiveSupport::Inflector.inflections do |inflect|
6 | # inflect.plural /^(ox)$/i, '\1en'
7 | # inflect.singular /^(ox)en/i, '\1'
8 | # inflect.irregular 'person', 'people'
9 | # inflect.uncountable %w( fish sheep )
10 | # end
11 |
--------------------------------------------------------------------------------
/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new mime types for use in respond_to blocks:
4 | # Mime::Type.register "text/richtext", :rtf
5 | # Mime::Type.register_alias "text/html", :iphone
6 |
--------------------------------------------------------------------------------
/config/initializers/new_rails_defaults.rb:
--------------------------------------------------------------------------------
1 | # These settings change the behavior of Rails 2 apps and will be defaults
2 | # for Rails 3. You can remove this initializer when Rails 3 is released.
3 |
4 | if defined?(ActiveRecord)
5 | # Include Active Record class name as root for JSON serialized output.
6 | ActiveRecord::Base.include_root_in_json = true
7 |
8 | # Store the full class name (including module namespace) in STI type column.
9 | ActiveRecord::Base.store_full_sti_class = true
10 | end
11 |
12 | # Use ISO 8601 format for JSON serialized times and dates.
13 | ActiveSupport.use_standard_json_time_format = true
14 |
15 | # Don't escape HTML entities in JSON, leave that for the #json_escape helper.
16 | # if you're including raw json in an HTML page.
17 | ActiveSupport.escape_html_entities_in_json = false
--------------------------------------------------------------------------------
/config/initializers/require.rb:
--------------------------------------------------------------------------------
1 | # include Taskboard version file
2 | require 'taskboard_version'
3 |
--------------------------------------------------------------------------------
/config/juggernaut_hosts.example.yml:
--------------------------------------------------------------------------------
1 | # You should list any juggernaut hosts here.
2 | # You need only specify the secret key if you're using that type of authentication (see juggernaut.yml)
3 | #
4 | # Name: Mapping:
5 | # :port internal push server's port
6 | # :host internal push server's host/ip
7 | # :public_host public push server's host/ip (accessible from external clients)
8 | # :public_port public push server's port
9 | # :secret_key (optional) shared secret (should map to the key specified in the push server's config)
10 | # :environment (optional) limit host to a particular RAILS_ENV
11 |
12 | :hosts:
13 | - :port: 5001
14 | :host: 127.0.0.1
15 | :public_host: 127.0.0.1 # change this to your public IP/host to make juggernaut accessible externally
16 | :public_port: 5001 # make sure this is the same as public port in juggernaut.yml config
17 | # :secret_key: your_secret_key
18 | # :environment: :development
19 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | ActionController::Routing::Routes.draw do |map|
2 | # The priority is based upon order of creation: first created -> highest priority.
3 |
4 | # Sample of regular route:
5 | # map.connect 'products/:id', :controller => 'catalog', :action => 'view'
6 | # Keep in mind you can assign values other than :controller and :action
7 |
8 | # Sample of named route:
9 | # map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'
10 | # This route can be invoked with purchase_url(:id => product.id)
11 | map.home 'home', :controller => 'project', :action => 'index'
12 |
13 | # Sample resource route (maps HTTP verbs to controller actions automatically):
14 | # map.resources :products
15 |
16 | # Sample resource route with options:
17 | # map.resources :products, :member => { :short => :get, :toggle => :post }, :collection => { :sold => :get }
18 |
19 | # Sample resource route with sub-resources:
20 | # map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller
21 |
22 | # Sample resource route with more complex sub-resources
23 | # map.resources :products do |products|
24 | # products.resources :comments
25 | # products.resources :sales, :collection => { :recent => :get }
26 | # end
27 |
28 | # Sample resource route within a namespace:
29 | # map.namespace :admin do |admin|
30 | # # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb)
31 | # admin.resources :products
32 | # end
33 |
34 | # You can have the root of your site routed with map.root -- just remember to delete public/index.html.
35 | map.root :controller => "project"
36 |
37 | # See how all your routes lay out with "rake routes"
38 |
39 | # Install the default routes as the lowest priority.
40 | # Note: These default routes make all actions in every controller accessible via GET requests. You should
41 | # consider removing the them or commenting them out if you're using named routes and resources.
42 | map.connect ':controller/:action/:id'
43 | map.connect ':controller/:action/:id.:format'
44 | end
45 |
--------------------------------------------------------------------------------
/config/taskboard.example.yml:
--------------------------------------------------------------------------------
1 | --- !ruby/object:TaskboardConfig
2 | jira_auth_data:
3 | jira.example.com:
4 | os_username: your_jira_username
5 | os_password: your_jira_password
6 | jira.other.example.com:
7 | os_username: your_other_jira_username
8 | os_password: your_other_jira_password
9 |
10 |
--------------------------------------------------------------------------------
/db/migrate/20081010142942_create_cards.rb:
--------------------------------------------------------------------------------
1 | class CreateCards < ActiveRecord::Migration
2 | def self.up
3 | create_table :cards do |t|
4 | t.text :name, :null => false
5 | t.text :notes, :null => true
6 | t.integer :taskboard_id
7 | t.integer :column_id
8 | t.integer :position, :null => true
9 | t.string :issue_no, :null => true, :limit => 128
10 | t.string :color, :null => true, :limit => 128
11 | t.string :url, :null => true
12 | t.timestamps
13 | end
14 | end
15 |
16 | def self.down
17 | drop_table :cards
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/db/migrate/20081013145250_create_taskboards.rb:
--------------------------------------------------------------------------------
1 | class CreateTaskboards < ActiveRecord::Migration
2 | def self.up
3 | create_table :taskboards do |t|
4 | t.text :name, :null => false
5 | t.timestamps
6 | end
7 | end
8 |
9 | def self.down
10 | drop_table :taskboards
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/db/migrate/20081013170754_create_columns.rb:
--------------------------------------------------------------------------------
1 | class CreateColumns < ActiveRecord::Migration
2 | def self.up
3 | create_table :columns do |t|
4 | t.text :name, :null => false
5 | t.integer :position, :null => true
6 | t.integer :taskboard_id, :null => false
7 | t.timestamps
8 | end
9 | end
10 |
11 | def self.down
12 | drop_table :columns
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/db/migrate/20081031114623_foreign_keys.rb:
--------------------------------------------------------------------------------
1 | require "migration_helpers"
2 |
3 | class ForeignKeys < ActiveRecord::Migration
4 | extend MigrationHelpers
5 |
6 | def self.up
7 | add_foreign_key(:cards, :taskboard_id, :taskboards)
8 | add_foreign_key(:cards, :column_id, :columns)
9 | add_foreign_key(:columns, :taskboard_id, :taskboards)
10 | end
11 |
12 | def self.down
13 | remove_foreign_key(:cards, :taskboard_id)
14 | remove_foreign_key(:cards, :column_id)
15 | remove_foreign_key(:columns, :taskboard_id)
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/db/migrate/20081127152023_acts_as_taggable_migration.rb:
--------------------------------------------------------------------------------
1 | class ActsAsTaggableMigration < ActiveRecord::Migration
2 | def self.up
3 | create_table :tags do |t|
4 | t.column :name, :string
5 | end
6 |
7 | create_table :taggings do |t|
8 | t.column :tag_id, :integer
9 | t.column :taggable_id, :integer
10 |
11 | # You should make sure that the column created is
12 | # long enough to store the required class names.
13 | t.column :taggable_type, :string
14 |
15 | t.column :created_at, :datetime
16 | end
17 |
18 | add_index :taggings, :tag_id
19 | add_index :taggings, [:taggable_id, :taggable_type]
20 | end
21 |
22 | def self.down
23 | drop_table :taggings
24 | drop_table :tags
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/db/migrate/20081205134317_create_hours.rb:
--------------------------------------------------------------------------------
1 | class CreateHours < ActiveRecord::Migration
2 | def self.up
3 | create_table :hours do |t|
4 | t.datetime :date, :null => false
5 | t.integer :left, :null => false
6 | t.integer :card_id
7 | t.timestamps
8 | end
9 | end
10 |
11 | def self.down
12 | drop_table :hours
13 | end
14 | end
15 |
--------------------------------------------------------------------------------
/db/migrate/20090317140555_create_sessions.rb:
--------------------------------------------------------------------------------
1 | class CreateSessions < ActiveRecord::Migration
2 | def self.up
3 | create_table :sessions do |t|
4 | t.string :session_id, :null => false
5 | t.text :data
6 | t.timestamps
7 | end
8 |
9 | add_index :sessions, :session_id
10 | add_index :sessions, :updated_at
11 | end
12 |
13 | def self.down
14 | drop_table :sessions
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/db/migrate/20090428084605_create_users.rb:
--------------------------------------------------------------------------------
1 | class CreateUsers < ActiveRecord::Migration
2 | def self.up
3 | create_table :users do |t|
4 | t.string :username, :null => false
5 | t.string :hashed_password, :null => false
6 | t.string :salt, :null => false
7 | t.boolean :editor
8 | t.string :email
9 | t.timestamps
10 | end
11 | end
12 |
13 | def self.down
14 | drop_table :users
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/db/migrate/20090428123003_add_default_users.rb:
--------------------------------------------------------------------------------
1 | class AddDefaultUsers < ActiveRecord::Migration
2 | def self.up
3 | User.create!(:username => "taskboard", :password => "taskboard", :editor => true)
4 | end
5 |
6 | def self.down
7 | User.delete_all
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/db/migrate/20090706124829_create_rows.rb:
--------------------------------------------------------------------------------
1 | require "migration_helpers"
2 |
3 | class CreateRows < ActiveRecord::Migration
4 | extend MigrationHelpers
5 |
6 | def self.up
7 | create_table :rows do |t|
8 | t.text :name, :null => false
9 | t.integer :position, :null => true
10 | t.integer :taskboard_id, :null => false
11 | t.timestamps
12 | end
13 |
14 | add_foreign_key(:rows, :taskboard_id, :taskboards)
15 | end
16 |
17 | def self.down
18 | remove_foreign_key(:rows, :taskboard_id)
19 |
20 | drop_table :rows
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/db/migrate/20090707130233_add_cards_to_rows.rb:
--------------------------------------------------------------------------------
1 | require "migration_helpers"
2 |
3 | class AddCardsToRows < ActiveRecord::Migration
4 | extend MigrationHelpers
5 |
6 | def self.up
7 | add_column :cards, :row_id, :integer
8 | add_foreign_key(:cards, :row_id, :rows)
9 |
10 | say_with_time 'Creating default rows for all existing taskboards' do
11 | Taskboard.find(:all).each do |taskboard|
12 | row = Row.create!(:name => "Default row", :taskboard_id => taskboard.id)
13 | taskboard.cards.each do |card|
14 | card.row_id = row.id;
15 | card.save!
16 | end
17 | end
18 | end
19 | end
20 |
21 | def self.down
22 | remove_foreign_key(:cards, :row_id)
23 | remove_column :cards, :row_id
24 |
25 | Row.delete_all
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/db/migrate/20090922095631_create_projects.rb:
--------------------------------------------------------------------------------
1 | class CreateProjects < ActiveRecord::Migration
2 | def self.up
3 | create_table :projects do |t|
4 | t.text :name, :null => false
5 | t.timestamps
6 | end
7 | end
8 |
9 | def self.down
10 | drop_table :projects
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/db/migrate/20090922100811_add_taskboards_to_projects.rb:
--------------------------------------------------------------------------------
1 | require "migration_helpers"
2 |
3 | class AddTaskboardsToProjects < ActiveRecord::Migration
4 | extend MigrationHelpers
5 |
6 | def self.up
7 | add_column :taskboards, :project_id, :integer
8 | add_foreign_key(:taskboards, :project_id, :projects)
9 |
10 | project = Project.create!(:name => "All taskboards")
11 | say_with_time 'Creating default project for all existing taskboards' do
12 | Taskboard.find(:all).each do |taskboard|
13 | taskboard.project = project
14 | taskboard.save!
15 | end
16 | end
17 | end
18 |
19 | def self.down
20 | remove_foreign_key(:taskboards, :project_id)
21 | remove_column :taskboards, :project_id
22 |
23 | Project.delete_all
24 | end
25 | end
26 |
27 |
--------------------------------------------------------------------------------
/lib/jira_integration.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | require 'net/http'
19 | require 'net/https'
20 | require 'uri'
21 | require 'taskboard_config'
22 |
23 | class JiraIntegration
24 |
25 | def self.get url
26 | uri = get_uri_to_xml(url)
27 |
28 | http = Net::HTTP.new(uri.host, uri.port)
29 | http.use_ssl = true if uri.port == Net::HTTP.https_default_port
30 |
31 | # append credentials
32 | credentials = self.auth_data[uri.host].to_a.collect{ |a| a.join('=') }.join('&')
33 | uri.query = uri.query.nil? ? credentials : uri.query + '&' + credentials
34 |
35 | http.get(uri.path + '?' + uri.query).body
36 | end
37 |
38 | def self.get_uri_to_xml url
39 | uri = URI.parse(url)
40 |
41 | # leave all request to xml file untouched
42 | unless uri.path.ends_with?('.xml')
43 |
44 | # check if it is request for single issue or bunch of them (IssueNavigator)
45 | if uri.path =~ /secure\/IssueNavigator.jspa/
46 |
47 | # distinguish between search results and filters
48 | if uri.query =~ /requestId=[\d]*$/
49 |
50 | # parse filter id
51 | filter_id = uri.query[/requestId=[\d]*$/][/\d+/]
52 | uri.path.sub!('secure/IssueNavigator.jspa',
53 | 'sr/jira.issueviews:searchrequest-xml/' + filter_id + '/SearchRequest-' + filter_id + '.xml')
54 | else
55 |
56 | # just modify path
57 | uri.path.sub!('secure/IssueNavigator.jspa',
58 | 'sr/jira.issueviews:searchrequest-xml/temp/SearchRequest.xml')
59 | end
60 |
61 | # remove 'mode' and 'requestId' parameters and add 'tempMax'
62 | uri.query.gsub!(/&?(mode=\w+|requestId=\w+|reset=\w+)/, '')
63 | uri.query += '&' unless uri.query.empty?
64 | uri.query += 'tempMax=1000'
65 |
66 | else
67 | # single issue
68 | issue_id = uri.path[/[\w-]*$/]
69 | uri.path = uri.path.sub('browse', 'si/jira.issueviews:issue-xml') + '/' + issue_id + '.xml'
70 | end
71 | end
72 | uri
73 | end
74 |
75 | def self.is_valid_url? url
76 | not self.auth_data.nil? and self.auth_data.keys.any? { |base| url.include? base }
77 | end
78 |
79 | private
80 |
81 | def self.auth_data
82 | TaskboardConfig.instance.jira_auth_data
83 | end
84 | end
85 |
86 |
--------------------------------------------------------------------------------
/lib/jira_parser.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | require 'rexml/document'
19 |
20 | include REXML
21 |
22 | class JiraParser
23 |
24 | attr_accessor :xml, :issues
25 |
26 | # TODO use SAX and optimize this method (http://www.rubyxml.com/articles/REXML/Stream_Parsing_with_REXML)
27 | def do_parse!
28 | doc = Document.new(xml)
29 | @issues = Array.new
30 | doc.root.each_element('channel/item') do |item|
31 | card = Card.new
32 | card.name = item.elements['summary'].text
33 | card.issue_no = item.elements['key'].text
34 | if (card.issue_no)
35 | card.url = item.elements['link'].text
36 | end
37 | @issues << card
38 | end
39 | end
40 |
41 | def self.is_jira_url url
42 | JiraIntegration.is_valid_url? url
43 | end
44 |
45 | def self.fetch_cards url
46 | issues_xml = JiraIntegration.get(url)
47 |
48 | # TODO: some kind of error instead of broken card
49 | unless issues_xml.include?(".
17 |
18 | module MigrationHelpers
19 |
20 | # TODO: MySQL friendly methods, do some cleanup while porting to other database
21 | def add_foreign_key(from_table, from_column, to_table)
22 | constraint_name = "fk_#{from_table}_#{from_column}"
23 | execute %{alter table #{from_table} add constraint #{constraint_name} foreign key (#{from_column}) references #{to_table}(id)}
24 | end
25 |
26 | def remove_foreign_key(from_table, from_column)
27 | constraint_name = "fk_#{from_table}_#{from_column}"
28 | execute %{alter table #{from_table} drop foreign key #{constraint_name}}
29 | end
30 |
31 | end
32 |
--------------------------------------------------------------------------------
/lib/taskboard_config.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | require 'yaml'
19 | require 'utils'
20 |
21 | class TaskboardConfig
22 | attr_accessor :jira_auth_data;
23 |
24 | def self.instance
25 | if @config.nil?
26 | @config_file_name = "config/taskboard.yml"
27 | @config = YAML.load_file(@config_file_name)
28 | end
29 | @config
30 |
31 | rescue Errno::ENOENT => e
32 | # TODO: log some error? -- but not with 'puts'
33 | @config = TaskboardConfig.new
34 | end
35 |
36 | # only for testing
37 | def self.reset
38 | @config = nil
39 | end
40 |
41 | end
42 |
--------------------------------------------------------------------------------
/lib/taskboard_version.rb:
--------------------------------------------------------------------------------
1 | TASKBOARD_VERSION = "10.01.26 Creole"
2 |
--------------------------------------------------------------------------------
/lib/url_parser.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | class UrlParser
19 |
20 | URL_REGEXP = /(http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.freeze
21 |
22 | def self.is_url url
23 | not (url =~ URL_REGEXP).nil?
24 | end
25 |
26 | def self.fetch_cards url
27 | url = url.gsub(/\/$/,'')
28 | Array.[](Card.new(:issue_no => url.gsub(/^.*\//,''), :url => url, :name => url))
29 | end
30 |
31 | end
32 |
33 |
--------------------------------------------------------------------------------
/lib/utils.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | def time description = '', &block
19 | start = Time.now
20 | yield
21 | puts "execution time of #{description.empty? ? block.to_s : description}: #{Time.now - start}"
22 | end
23 |
24 | def get_file_as_string(filename)
25 | data = ''
26 | f = File.open(filename, "r")
27 | f.each_line do |line|
28 | data += line
29 | end
30 | return data
31 | end
32 |
33 |
--------------------------------------------------------------------------------
/log/report/readme:
--------------------------------------------------------------------------------
1 | Report directory
2 |
--------------------------------------------------------------------------------
/public/404.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 | The page you were looking for doesn't exist (404)
9 |
21 |
22 |
23 |
24 |
25 |
26 |
The page you were looking for doesn't exist.
27 |
You may have mistyped the address or the page may have moved.
17 |
18 |
19 |
--------------------------------------------------------------------------------
/spec/javascripts/spec_helper.js:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2009 Cognifide
3 | *
4 | * This file is part of Taskboard.
5 | *
6 | * Taskboard is free software: you can redistribute it and/or modify
7 | * it under the terms of the GNU General Public License as published by
8 | * the Free Software Foundation, either version 3 of the License, or
9 | * (at your option) any later version.
10 | *
11 | * Taskboard is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | * GNU General Public License for more details.
15 |
16 | * You should have received a copy of the GNU General Public License
17 | * along with Taskboard. If not, see .
18 | */
19 |
20 | // Use this file to require common dependencies or to setup useful test functions.
21 |
22 | Screw.Matchers["be_function"] = {
23 | match: function(expected, actual) {
24 | return typeof actual == "function";
25 | },
26 | failure_message: function(expected, actual, not) {
27 | return 'expected ' + $.print(actual) + (not ? ' not' : '') + ' to be function';
28 | }
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/spec/lib/taskboard_config_spec.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
19 | require 'yaml'
20 | require 'taskboard_config'
21 |
22 | describe TaskboardConfig do
23 |
24 | it "should parse yml file" do
25 | conf = TaskboardConfig.new
26 | conf.jira_auth_data = {"some.url.com" => { "os_password" => "pass", "os_username" => "user" } }
27 |
28 | YAML.should_receive(:load_file).and_return(conf)
29 |
30 | TaskboardConfig.reset
31 | TaskboardConfig.instance.jira_auth_data["some.url.com"]["os_password"].should eql("pass")
32 | TaskboardConfig.instance.jira_auth_data["some.url.com"]["os_username"].should eql("user")
33 | end
34 |
35 | it "should log errors" do
36 | YAML.should_receive(:load_file).and_raise(Errno::ENOENT)
37 |
38 | TaskboardConfig.reset
39 | TaskboardConfig.instance.jira_auth_data.nil?.should be_true
40 | end
41 |
42 | end
43 |
44 |
--------------------------------------------------------------------------------
/spec/lib/taskboard_version_spec.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
19 | require 'taskboard_version'
20 |
21 | describe TASKBOARD_VERSION do
22 |
23 | it "should be a text with correct format" do
24 | TASKBOARD_VERSION.should_not be_nil
25 | TASKBOARD_VERSION.should be_a(String)
26 | TASKBOARD_VERSION.should match(/^[0-9]{2}\.[0-9]{2}(\.[0-9]{2})?.*/)
27 | end
28 |
29 | end
30 |
31 |
--------------------------------------------------------------------------------
/spec/lib/url_parser_spec.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
19 | require 'url_parser'
20 |
21 | describe UrlParser, "while helping with url recognition" do
22 |
23 | it "should recognize valid urls" do
24 | [ 'https://jira.cognifide.com/jira/browse/TASKBOARD-2',
25 | 'https://localhost:3000/app', 'http://google.com',
26 | 'http://google.com/', 'http://192.168.1.1',
27 | 'http://127.0.0.1:6363', 'http://127.0.0.1:6363',
28 | 'http://192.168.1.1/jira'].each do |url|
29 | UrlParser.is_url(url).should be_true
30 | end
31 |
32 | UrlParser.is_url('My new card!').should be_false
33 | end
34 |
35 | end
36 |
37 | describe UrlParser do
38 |
39 | it "should response to :fetch_cards method" do
40 | UrlParser.should respond_to(:fetch_cards)
41 | end
42 |
43 | it "should fetch a card for given url" do
44 | check_card_name('https://jira.cognifide.com/jira/browse/TASKBOARD-2', 'https://jira.cognifide.com/jira/browse/TASKBOARD-2', 'TASKBOARD-2');
45 | check_card_name('https://jira.cognifide.com/jira/browse/TASKBOARD-3/', 'https://jira.cognifide.com/jira/browse/TASKBOARD-3','TASKBOARD-3');
46 | end
47 |
48 | private
49 |
50 | def check_card_name(based_url, url, name)
51 | cards = UrlParser.fetch_cards(based_url)
52 | cards.size.should eql(1)
53 | cards.last.name.should eql(url)
54 | cards.last.issue_no.should eql(name)
55 | cards.last.url.should eql(url)
56 | end
57 |
58 | end
59 |
--------------------------------------------------------------------------------
/spec/lib/utils_spec.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
19 | require 'utils'
20 |
21 | describe "Utils" do
22 |
23 | context "time function" do
24 |
25 | it "should print execution time of given block" do
26 | self.should_receive(:puts).with(/execution time of test/)
27 | time 'test' do
28 | (1..1000).each { }
29 | end
30 | end
31 |
32 | end
33 |
34 | end
35 |
--------------------------------------------------------------------------------
/spec/models/hour_spec.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
19 |
20 | describe Hour do
21 | before(:each) do
22 | @valid_attributes = {
23 | :date => Time.new,
24 | :left => 3
25 | }
26 | end
27 |
28 | it "should create a new instance given valid attributes" do
29 | Hour.create!(@valid_attributes)
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/spec/models/project_spec.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
19 |
20 | describe Project do
21 | fixtures :projects, :taskboards
22 |
23 | it "should create a new instance with given name" do
24 | Project.create!(:name => "Test Project")
25 | end
26 |
27 | it "should not be valid with empty name" do
28 | [nil, "", " ", " " ].each { |invalid_name|
29 | project = Project.new(:name => invalid_name)
30 | project.should_not be_valid
31 | }
32 | end
33 |
34 | it "should have correct number of taskboards assigned" do
35 | project = projects(:sample_project)
36 | project.should have_at_least(1).taskboard
37 | end
38 |
39 | it "should define default project's name" do
40 | Project::DEFAULT_NAME.should_not be_empty
41 | end
42 |
43 | end
44 |
--------------------------------------------------------------------------------
/spec/models/row_spec.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
19 |
20 | describe Row do
21 | fixtures :taskboards
22 |
23 | before(:each) do
24 | @valid_attributes = {
25 | :name => 'TODO',
26 | :position => 1,
27 | :taskboard_id => taskboards(:scrum_taskboard).id
28 | }
29 | end
30 |
31 | it "should create a new instance given valid attributes" do
32 | Row.create!(@valid_attributes)
33 | end
34 | end
35 |
36 | describe Row, "while working with database" do
37 | fixtures :taskboards, :columns, :rows, :cards
38 |
39 | it "should have non-empty collection of rows" do
40 | Row.find(:all).should_not be_empty
41 | end
42 |
43 | it "should allow inserting new row at given position" do
44 | @taskboard = taskboards(:scrum_taskboard)
45 | @row_1 = rows(:scrum_user_row)
46 | @row_2 = rows(:scrum_owner_row)
47 | row = Row.create!(:name => 'new row', :taskboard => @taskboard)
48 | row.insert_at(2)
49 | row.higher_item.should eql(@row_1)
50 | row.lower_item.should eql(@row_2)
51 | end
52 |
53 | it "should define default name" do
54 | Row::DEFAULT_NAME.should_not be_empty
55 | end
56 |
57 | it "should contain valid number of cards" do
58 | row = rows(:demo_first_row)
59 | row.should have_at_least(1).card
60 | end
61 |
62 | it "should get cards in given row" do
63 | column = columns(:scrum_todo_column)
64 | row = rows(:scrum_owner_row)
65 | row.cards.in_column(column).length.should < row.cards.length
66 | end
67 |
68 | it "should clone name and position" do
69 | row = rows(:demo_first_row)
70 | clonned = row.clone
71 |
72 | clonned.class.should be(Row)
73 | clonned.should_not eql(row)
74 | clonned.name.should eql(row.name)
75 | clonned.position.should eql(row.position)
76 | clonned.taskboard_id.should eql(row.taskboard_id)
77 |
78 | clonned = row.clone 234
79 |
80 | clonned.class.should be(Row)
81 | clonned.should_not eql(row)
82 | clonned.name.should eql(row.name)
83 | clonned.position.should eql(row.position)
84 | clonned.taskboard_id.should eql(234)
85 | end
86 |
87 | end
88 |
--------------------------------------------------------------------------------
/spec/models/user_spec.rb:
--------------------------------------------------------------------------------
1 | # Copyright (C) 2009 Cognifide
2 | #
3 | # This file is part of Taskboard.
4 | #
5 | # Taskboard is free software: you can redistribute it and/or modify
6 | # it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or
8 | # (at your option) any later version.
9 | #
10 | # Taskboard is distributed in the hope that it will be useful,
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 | # GNU General Public License for more details.
14 | #
15 | # You should have received a copy of the GNU General Public License
16 | # along with Taskboard. If not, see .
17 |
18 | require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
19 |
20 | describe User do
21 | fixtures :users
22 |
23 | it "should save hashed password when password is set" do
24 | user = User.new(:username => "testuser", :password => "testpassword")
25 | user.hashed_password.should_not be_empty
26 | user.hashed_password.should_not eql("testpassword")
27 | user.password.should eql("testpassword")
28 |
29 | user.valid?.should eql(true)
30 | end
31 |
32 | it "should not allow to save user without password" do
33 | user = User.new(:username => "testuser")
34 | user.valid?.should eql(false)
35 | end
36 |
37 | it "should not allow creating second user with same username" do
38 | user1 = User.new(:username => "name", :password => "testpassword")
39 | user1.save
40 | user2 = User.new(:username => "name", :password => "testpassword")
41 | user2.valid?.should eql(false)
42 | end
43 |
44 | it "should create some salt" do
45 | salt1 = User.new(:username => "name", :password => "password").salt
46 | salt1.should_not be_empty
47 | salt2 = User.new(:username => "name", :password => "password").salt
48 | salt2.should_not be_empty
49 | salt2.should_not eql(salt1)
50 | end
51 |
52 |
53 | it "should authenticate user if correct password is given" do
54 | user = users(:test_editor)
55 | authenticated_user = User.authenticate(user.username, "editor_password")
56 | authenticated_user.should_not be_nil
57 | authenticated_user.should eql(user)
58 | end
59 |
60 | it "should authenticate user if wrong password is given" do
61 | user = users(:test_editor)
62 | authenticated_user = User.authenticate(user.username, "wrongpassword")
63 | authenticated_user.should be_nil
64 | end
65 |
66 | it "should authenticate user if wrong username is given" do
67 | authenticated_user = User.authenticate("fakeuser", "password")
68 | authenticated_user.should be_nil
69 | end
70 | end
71 |
72 |
--------------------------------------------------------------------------------
/vendor/plugins/acts_as_list/README:
--------------------------------------------------------------------------------
1 | ActsAsList
2 | ==========
3 |
4 | This acts_as extension provides the capabilities for sorting and reordering a number of objects in a list. The class that has this specified needs to have a +position+ column defined as an integer on the mapped database table.
5 |
6 |
7 | Example
8 | =======
9 |
10 | class TodoList < ActiveRecord::Base
11 | has_many :todo_items, :order => "position"
12 | end
13 |
14 | class TodoItem < ActiveRecord::Base
15 | belongs_to :todo_list
16 | acts_as_list :scope => :todo_list
17 | end
18 |
19 | todo_list.first.move_to_bottom
20 | todo_list.last.move_higher
21 |
22 |
23 | Copyright (c) 2007 David Heinemeier Hansson, released under the MIT license
--------------------------------------------------------------------------------
/vendor/plugins/acts_as_list/init.rb:
--------------------------------------------------------------------------------
1 | $:.unshift "#{File.dirname(__FILE__)}/lib"
2 | require 'active_record/acts/list'
3 | ActiveRecord::Base.class_eval { include ActiveRecord::Acts::List }
4 |
--------------------------------------------------------------------------------
/vendor/plugins/acts_as_taggable_on_steroids/MIT-LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2006 Jonathan Viney
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/vendor/plugins/acts_as_taggable_on_steroids/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rake'
2 | require 'rake/testtask'
3 | require 'rake/rdoctask'
4 |
5 | desc 'Default: run unit tests.'
6 | task :default => :test
7 |
8 | desc 'Test the acts_as_taggable_on_steroids plugin.'
9 | Rake::TestTask.new(:test) do |t|
10 | t.libs << 'lib'
11 | t.pattern = 'test/**/*_test.rb'
12 | t.verbose = true
13 | end
14 |
15 | desc 'Generate documentation for the acts_as_taggable_on_steroids plugin.'
16 | Rake::RDocTask.new(:rdoc) do |rdoc|
17 | rdoc.rdoc_dir = 'rdoc'
18 | rdoc.title = 'Acts As Taggable On Steroids'
19 | rdoc.options << '--line-numbers' << '--inline-source'
20 | rdoc.rdoc_files.include('README')
21 | rdoc.rdoc_files.include('lib/**/*.rb')
22 | end
23 |
--------------------------------------------------------------------------------
/vendor/plugins/acts_as_taggable_on_steroids/generators/acts_as_taggable_migration/acts_as_taggable_migration_generator.rb:
--------------------------------------------------------------------------------
1 | class ActsAsTaggableMigrationGenerator < Rails::Generator::Base
2 | def manifest
3 | record do |m|
4 | m.migration_template 'migration.rb', 'db/migrate'
5 | end
6 | end
7 |
8 | def file_name
9 | "acts_as_taggable_migration"
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/vendor/plugins/acts_as_taggable_on_steroids/generators/acts_as_taggable_migration/templates/migration.rb:
--------------------------------------------------------------------------------
1 | class ActsAsTaggableMigration < ActiveRecord::Migration
2 | def self.up
3 | create_table :tags do |t|
4 | t.column :name, :string
5 | end
6 |
7 | create_table :taggings do |t|
8 | t.column :tag_id, :integer
9 | t.column :taggable_id, :integer
10 |
11 | # You should make sure that the column created is
12 | # long enough to store the required class names.
13 | t.column :taggable_type, :string
14 |
15 | t.column :created_at, :datetime
16 | end
17 |
18 | add_index :taggings, :tag_id
19 | add_index :taggings, [:taggable_id, :taggable_type]
20 | end
21 |
22 | def self.down
23 | drop_table :taggings
24 | drop_table :tags
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/vendor/plugins/acts_as_taggable_on_steroids/init.rb:
--------------------------------------------------------------------------------
1 | require File.dirname(__FILE__) + '/lib/acts_as_taggable'
2 |
--------------------------------------------------------------------------------
/vendor/plugins/acts_as_taggable_on_steroids/lib/tag.rb:
--------------------------------------------------------------------------------
1 | class Tag < ActiveRecord::Base
2 | has_many :taggings, :dependent => :destroy
3 |
4 | validates_presence_of :name
5 | validates_uniqueness_of :name
6 |
7 | cattr_accessor :destroy_unused
8 | self.destroy_unused = false
9 |
10 | # LIKE is used for cross-database case-insensitivity
11 | def self.find_or_create_with_like_by_name(name)
12 | find(:first, :conditions => ["name LIKE ?", name]) || create(:name => name)
13 | end
14 |
15 | def ==(object)
16 | super || (object.is_a?(Tag) && name == object.name)
17 | end
18 |
19 | def to_s
20 | name
21 | end
22 |
23 | def count
24 | read_attribute(:count).to_i
25 | end
26 |
27 | class << self
28 | # Calculate the tag counts for all tags.
29 | # :start_at - Restrict the tags to those created after a certain time
30 | # :end_at - Restrict the tags to those created before a certain time
31 | # :conditions - A piece of SQL conditions to add to the query
32 | # :limit - The maximum number of tags to return
33 | # :order - A piece of SQL to order by. Eg 'count desc' or 'taggings.created_at desc'
34 | # :at_least - Exclude tags with a frequency less than the given value
35 | # :at_most - Exclude tags with a frequency greater than the given value
36 | def counts(options = {})
37 | find(:all, options_for_counts(options))
38 | end
39 |
40 | def options_for_counts(options = {})
41 | options.assert_valid_keys :start_at, :end_at, :conditions, :at_least, :at_most, :order, :limit, :joins
42 | options = options.dup
43 |
44 | start_at = sanitize_sql(["#{Tagging.table_name}.created_at >= ?", options.delete(:start_at)]) if options[:start_at]
45 | end_at = sanitize_sql(["#{Tagging.table_name}.created_at <= ?", options.delete(:end_at)]) if options[:end_at]
46 |
47 | conditions = [
48 | options.delete(:conditions),
49 | start_at,
50 | end_at
51 | ].compact
52 |
53 | conditions = conditions.any? ? conditions.join(' AND ') : nil
54 |
55 | joins = ["INNER JOIN #{Tagging.table_name} ON #{Tag.table_name}.id = #{Tagging.table_name}.tag_id"]
56 | joins << options.delete(:joins) if options[:joins]
57 |
58 | at_least = sanitize_sql(['COUNT(*) >= ?', options.delete(:at_least)]) if options[:at_least]
59 | at_most = sanitize_sql(['COUNT(*) <= ?', options.delete(:at_most)]) if options[:at_most]
60 | having = [at_least, at_most].compact.join(' AND ')
61 | group_by = "#{Tag.table_name}.id, #{Tag.table_name}.name HAVING COUNT(*) > 0"
62 | group_by << " AND #{having}" unless having.blank?
63 |
64 | { :select => "#{Tag.table_name}.id, #{Tag.table_name}.name, COUNT(*) AS count",
65 | :joins => joins.join(" "),
66 | :conditions => conditions,
67 | :group => group_by
68 | }.update(options)
69 | end
70 | end
71 | end
72 |
--------------------------------------------------------------------------------
/vendor/plugins/acts_as_taggable_on_steroids/lib/tag_counts_extension.rb:
--------------------------------------------------------------------------------
1 | # Deprecated
2 | module TagCountsExtension #:nodoc:
3 | end
4 |
--------------------------------------------------------------------------------
/vendor/plugins/acts_as_taggable_on_steroids/lib/tag_list.rb:
--------------------------------------------------------------------------------
1 | class TagList < Array
2 | cattr_accessor :delimiter
3 | self.delimiter = ','
4 |
5 | def initialize(*args)
6 | add(*args)
7 | end
8 |
9 | # Add tags to the tag_list. Duplicate or blank tags will be ignored.
10 | #
11 | # tag_list.add("Fun", "Happy")
12 | #
13 | # Use the :parse option to add an unparsed tag string.
14 | #
15 | # tag_list.add("Fun, Happy", :parse => true)
16 | def add(*names)
17 | extract_and_apply_options!(names)
18 | concat(names)
19 | clean!
20 | self
21 | end
22 |
23 | # Remove specific tags from the tag_list.
24 | #
25 | # tag_list.remove("Sad", "Lonely")
26 | #
27 | # Like #add, the :parse option can be used to remove multiple tags in a string.
28 | #
29 | # tag_list.remove("Sad, Lonely", :parse => true)
30 | def remove(*names)
31 | extract_and_apply_options!(names)
32 | delete_if { |name| names.include?(name) }
33 | self
34 | end
35 |
36 | # Toggle the presence of the given tags.
37 | # If a tag is already in the list it is removed, otherwise it is added.
38 | def toggle(*names)
39 | extract_and_apply_options!(names)
40 |
41 | names.each do |name|
42 | include?(name) ? delete(name) : push(name)
43 | end
44 |
45 | clean!
46 | self
47 | end
48 |
49 | # Transform the tag_list into a tag string suitable for edting in a form.
50 | # The tags are joined with TagList.delimiter and quoted if necessary.
51 | #
52 | # tag_list = TagList.new("Round", "Square,Cube")
53 | # tag_list.to_s # 'Round, "Square,Cube"'
54 | def to_s
55 | clean!
56 |
57 | map do |name|
58 | name.include?(delimiter) ? "\"#{name}\"" : name
59 | end.join(delimiter.ends_with?(" ") ? delimiter : "#{delimiter} ")
60 | end
61 |
62 | private
63 | # Remove whitespace, duplicates, and blanks.
64 | def clean!
65 | reject!(&:blank?)
66 | map!(&:strip)
67 | uniq!
68 | end
69 |
70 | def extract_and_apply_options!(args)
71 | options = args.last.is_a?(Hash) ? args.pop : {}
72 | options.assert_valid_keys :parse
73 |
74 | if options[:parse]
75 | args.map! { |a| self.class.from(a) }
76 | end
77 |
78 | args.flatten!
79 | end
80 |
81 | class << self
82 | # Returns a new TagList using the given tag string.
83 | #
84 | # tag_list = TagList.from("One , Two, Three")
85 | # tag_list # ["One", "Two", "Three"]
86 | def from(source)
87 | returning new do |tag_list|
88 |
89 | case source
90 | when Array
91 | tag_list.add(source)
92 | else
93 | string = source.to_s.dup
94 |
95 | # Parse the quoted tags
96 | [
97 | /\s*#{delimiter}\s*(['"])(.*?)\1\s*/,
98 | /^\s*(['"])(.*?)\1\s*#{delimiter}?/
99 | ].each do |re|
100 | string.gsub!(re) { tag_list << $2; "" }
101 | end
102 |
103 | tag_list.add(string.split(delimiter))
104 | end
105 | end
106 | end
107 | end
108 | end
109 |
--------------------------------------------------------------------------------
/vendor/plugins/acts_as_taggable_on_steroids/lib/tagging.rb:
--------------------------------------------------------------------------------
1 | class Tagging < ActiveRecord::Base #:nodoc:
2 | belongs_to :tag
3 | belongs_to :taggable, :polymorphic => true
4 |
5 | def after_destroy
6 | if Tag.destroy_unused
7 | if tag.taggings.count.zero?
8 | tag.destroy
9 | end
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/vendor/plugins/acts_as_taggable_on_steroids/lib/tags_helper.rb:
--------------------------------------------------------------------------------
1 | module TagsHelper
2 | # See the README for an example using tag_cloud.
3 | def tag_cloud(tags, classes)
4 | return if tags.empty?
5 |
6 | max_count = tags.sort_by(&:count).last.count.to_f
7 |
8 | tags.each do |tag|
9 | index = ((tag.count / max_count) * (classes.size - 1)).round
10 | yield tag, classes[index]
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2008-2009 Relevance, Inc.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/LICENSE-Screw.Unit:
--------------------------------------------------------------------------------
1 | Copyright (c) 2008 Nick Kallen
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/LICENSE-Smoke:
--------------------------------------------------------------------------------
1 | Copyright (c) 2008 Andy Kent
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/Rakefile:
--------------------------------------------------------------------------------
1 | ENV["BLUE_RIDGE_PREFIX"] = File.dirname(__FILE__)
2 | import File.dirname(__FILE__) + '/tasks/javascript_testing_tasks.rake'
3 |
4 | gem "spicycode-micronaut", ">= 0.2.4"
5 | require 'micronaut'
6 | require 'micronaut/rake_task'
7 |
8 | namespace :test do
9 | desc "Run all micronaut examples using rcov"
10 | Micronaut::RakeTask.new :rubies do |t|
11 | t.pattern = "spec/rubies/**/*_spec.rb"
12 | end
13 | end
14 |
15 | task :default => ["test:rubies", "test:javascripts"]
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/TODO.taskpaper:
--------------------------------------------------------------------------------
1 | Release 1:
2 | - cleanup README
3 | - include correct copyright notices of vendored software @done
4 | - add API documentation (require, etc) @done
5 | - explain that we're jQuery-opinionated, but give jQuery.noConflict() example for Prototype @done
6 | - list Java (version?) as a system requirement
7 | - improve test output for command line @done(2009-01-30)
8 | - merge back to Relevance's javascript_testing project on GitHub @done
9 | - change generators to use Screw.Unit style instead of JS-Spec @done
10 | - test that env-js works with DOCTYPEs now? @done(2009-01-30)
11 | - rake task to open fixtures in your favorite web browser? @done
12 | - make the generator check for "test", "spec", and then "examples" directory to create the "javascript" dir @done(2009-04-11)
13 | - support Prototype @done
14 | - support jQuery 1.3.x @env.js @done(2009-05-08)
15 | - in browser @done(2009-04-11)
16 | - from command line @done(2009-05-08)
17 | - when clicking on a describe or it block in browser, run focused tests (thanks rsim!) @done(2009-04-11)
18 | - fix timing issues of "require" calls in browser tests often causing first test to fail @done(2009-04-11)
19 | - include Smoke for mocking @done(2009-04-11)
20 | - automatically require @done(2009-04-11)
21 | - command line @done(2009-04-11)
22 | - browser @done(2009-04-11)
23 | - add examples of mocking to README @done
24 | - improve mocking example in README - show code under test
25 | - caveat re stubbing in README
26 | - change name of plugin @done
27 | - change the relevance github fork's name @done
28 | - create a "javascript_testing" github project with a README that points folks to the new name @done
29 | - what is the new name? --> "blue-ridge" @done
30 | Release 2:
31 | - Document TextMate support
32 | - fork the screw.unit text mate bundle
33 | - add the TextMate runner from the karnowski/javascript_testing Textmate bundle
34 | - "git clone git://github.com/coreyti/screw-unit-tmbundle.git screw-unit.tmbundle"
35 | - have to remove the "run" macro there
36 | - "git clone git://github.com/karnowski/javascript-testing-tmbundle.git javascript-testing.tmbundle"
37 | - needs to be smart enough to look for spec, test, or examples -- right now hard-coded to "test"
38 | - known text-mate issue with builder.rb: http://robsanheim.com/2007/12/07/fixing-textmate-test-issues-blank_slate_method_added-stack-level-too-deep-systemstackerror/
39 | - might also have to move it in the "Pristine Copy" version too
40 | - sprockets support?
41 | - improve "require" to take an array and chain them together in order
42 | - handle display of nested describes better for command-line
43 |
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/generators/blue_ridge/blue_ridge_generator.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path(File.dirname(__FILE__) + '/../../lib/blue_ridge')
2 |
3 | class BlueRidgeGenerator < Rails::Generator::Base
4 | def manifest
5 | record do |m|
6 | base_dir = BlueRidge.javascript_spec_dir
7 |
8 | m.directory base_dir
9 | m.file 'application_spec.js', "#{base_dir}/application_spec.js"
10 | m.file 'spec_helper.js', "#{base_dir}/spec_helper.js"
11 |
12 | m.directory "#{base_dir}/fixtures"
13 | m.file 'application.html', "#{base_dir}/fixtures/application.html"
14 | m.file 'screw.css', "#{base_dir}/fixtures/screw.css"
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/generators/blue_ridge/templates/application.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Application | JavaScript Testing Results
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/generators/blue_ridge/templates/application_spec.js:
--------------------------------------------------------------------------------
1 | require("spec_helper.js");
2 | require("../../public/javascripts/application.js");
3 |
4 | Screw.Unit(function(){
5 | describe("Your application javascript", function(){
6 | it("does something", function(){
7 | expect("hello").to(equal, "hello");
8 | });
9 |
10 | it("accesses the DOM from fixtures/application.html", function(){
11 | expect($('.select_me').length).to(equal, 2);
12 | });
13 | });
14 | });
15 |
16 |
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/generators/blue_ridge/templates/screw.css:
--------------------------------------------------------------------------------
1 | html {
2 | padding: 0.5em;
3 | font-family: Georgia, serif;
4 | background: #EDEBD5;
5 | }
6 |
7 | li {
8 | list-style-type: none;
9 | }
10 |
11 | .focused {
12 | background-color: #F4F2E4;
13 | }
14 |
15 | .focused * {
16 | opacity: 1.0;
17 | }
18 |
19 | h1, h2, p {
20 | opacity: 0.4;
21 | }
22 |
23 | .describes {
24 | padding-left: 0;
25 | }
26 |
27 | .describes h1 {
28 | font-size: 1.1em;
29 | color: #877C21;
30 | line-height: 1.8em;
31 | margin: 0pt 0pt 0.6em;
32 | border-bottom: 1px solid transparent;
33 | }
34 |
35 | .describes h1:hover {
36 | cursor: pointer;
37 | color: #000;
38 | background-color: #F4F2E4;
39 | border-bottom: 1px solid #9A8E51;
40 | }
41 |
42 | .describes .describe {
43 | margin-left: 0.6em;
44 | padding-left: 0.6em;
45 | border: 1px dashed #999;
46 | }
47 |
48 | .describes .describe .its {}
49 |
50 | .describes .describe .its .it {
51 | list-style-type: lower-roman;
52 | list-style-position: outside;
53 | }
54 |
55 | .describes .describe .its .it h2 {
56 | font-weight: normal;
57 | font-style: italic;
58 | padding-left: 0.5em;
59 | font-size: 1.0em;
60 | color: #877C21;
61 | line-height: 1.8em;
62 | margin: 0 0 0.5em;
63 | border-bottom: 1px solid transparent;
64 | }
65 |
66 | .describes .describe .its .it.enqueued h2 {
67 | background-color: #CC6600;
68 | color: white !important;
69 | }
70 |
71 | .describes .describe .its .it.passed h2 {
72 | background-color: #5A753D;
73 | color: white !important;
74 | }
75 |
76 | .describes .describe .its .it.failed h2 {
77 | background-color: #993300;
78 | color: white !important;
79 | }
80 |
81 | .describes .describe .its .it.failed p {
82 | margin-left: 1em;
83 | color: #993300;
84 | }
85 |
86 | .describes .describe .its .it h2:hover {
87 | cursor: pointer;
88 | color: #000 !important;
89 | border-bottom: 1px solid #9A8E51;
90 | }
91 |
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/generators/blue_ridge/templates/spec_helper.js:
--------------------------------------------------------------------------------
1 | // Use this file to require common dependencies or to setup useful test functions.
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/generators/javascript_spec/javascript_spec_generator.rb:
--------------------------------------------------------------------------------
1 | class JavascriptSpecGenerator < Rails::Generator::NamedBase
2 | def manifest
3 | file_path_with_spec, file_path_without_spec = file_path_with_and_without_spec
4 |
5 | record do |m|
6 | base_dir = BlueRidge.javascript_spec_dir
7 |
8 | m.directory base_dir
9 | m.directory "#{base_dir}/fixtures"
10 |
11 | options = {:class_name_without_spec => class_name_without_spec, :file_path_without_spec => file_path_without_spec}
12 | m.template 'javascript_spec.js.erb', "#{base_dir}/#{file_path_with_spec}.js", :assigns => options
13 | m.template 'fixture.html.erb', "#{base_dir}/fixtures/#{file_path_without_spec}.html", :assigns => options
14 | end
15 | end
16 |
17 | def file_path_with_and_without_spec
18 | if (file_path =~ /_spec$/i)
19 | [file_path, file_path.gsub(/_spec$/, "")]
20 | else
21 | [file_path + "_spec", file_path]
22 | end
23 | end
24 |
25 | def class_name_without_spec
26 | (class_name =~ /Spec$/) ? class_name.gsub(/Spec$/, "") : class_name
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/generators/javascript_spec/templates/fixture.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | <%= class_name_without_spec %> | JavaScript Testing Results
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/generators/javascript_spec/templates/javascript_spec.js.erb:
--------------------------------------------------------------------------------
1 | require("spec_helper.js");
2 | require("../../public/javascripts/<%= file_path_without_spec %>.js");
3 |
4 | Screw.Unit(function(){
5 | describe("<%= class_name_without_spec %>", function(){
6 | it("does something", function(){
7 | expect("hello").to(equal, "hello");
8 | });
9 | });
10 | });
11 |
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/lib/blue-ridge.js:
--------------------------------------------------------------------------------
1 | var BLUE_RIDGE_LIB_PREFIX = BLUE_RIDGE_LIB_PREFIX || "../../vendor/plugins/blue-ridge/lib/";
2 |
3 | var BlueRidge = {
4 | require: function(url, callback){
5 | // add a '../' prefix to all JavaScript paths because we expect to be ran from one of:
6 | // * test/javascript/fixtures
7 | // * specs/javascripts/fixtures
8 | // * examples/javascripts/fixtures
9 | url = "../" + url;
10 |
11 | var head = document.getElementsByTagName("head")[0];
12 | var script = document.createElement("script");
13 | script.src = url;
14 |
15 | if(callback){
16 | var done = false;
17 | // Attach handlers for all browsers
18 | script.onload = script.onreadystatechange = function(){
19 | if (!done && (!this.readyState ||
20 | this.readyState == "loaded" || this.readyState == "complete") ) {
21 | done = true;
22 | callback.call();
23 | // Handle memory leak in IE
24 | script.onload = script.onreadystatechange = null;
25 | head.removeChild( script );
26 | }
27 | };
28 | };
29 | head.appendChild(script);
30 | },
31 |
32 | debug: function(message){
33 | document.writeln(message + " ");
34 | },
35 |
36 | deriveSpecNameFromCurrentFile: function(){
37 | var file_prefix = new String(window.location).match(/.*\/(.*?)\.html/)[1];
38 | return file_prefix + "_spec.js";
39 | }
40 | };
41 |
42 | var require = require || BlueRidge.require;
43 | var debug = debug || BlueRidge.debug;
44 |
45 | // all required js libs are now nested to load properly
46 |
47 | require(BLUE_RIDGE_LIB_PREFIX + "jquery-1.3.2.js", function(){
48 | require(BLUE_RIDGE_LIB_PREFIX + "jquery.fn.js", function(){
49 | require(BLUE_RIDGE_LIB_PREFIX + "jquery.print.js", function(){
50 | require(BLUE_RIDGE_LIB_PREFIX + "screw.builder.js", function(){
51 | require(BLUE_RIDGE_LIB_PREFIX + "screw.matchers.js", function(){
52 | require(BLUE_RIDGE_LIB_PREFIX + "screw.events.js", function(){
53 | require(BLUE_RIDGE_LIB_PREFIX + "screw.behaviors.js", function(){
54 | require(BLUE_RIDGE_LIB_PREFIX + "smoke.core.js", function(){
55 | require(BLUE_RIDGE_LIB_PREFIX + "smoke.mock.js", function(){
56 | require(BLUE_RIDGE_LIB_PREFIX + "smoke.stub.js", function(){
57 | require(BLUE_RIDGE_LIB_PREFIX + "screw.mocking.js",function(){
58 |
59 | require(BLUE_RIDGE_LIB_PREFIX + "smok.js",function(){
60 | require(BLUE_RIDGE_LIB_PREFIX + "screw.smok.js",function(){
61 |
62 | require(BlueRidge.deriveSpecNameFromCurrentFile());
63 |
64 | });
65 | });
66 |
67 | });
68 | });
69 | });
70 | });
71 | });
72 | });
73 | });
74 | });
75 | });
76 | });
77 | });
78 |
79 |
80 |
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/lib/blue_ridge.rb:
--------------------------------------------------------------------------------
1 | module BlueRidge
2 | JavaScriptSpecDirs = ["examples/javascripts", "spec/javascripts", "test/javascript"]
3 |
4 | def self.plugin_prefix
5 | ENV["BLUE_RIDGE_PREFIX"] || "#{RAILS_ROOT}/vendor/plugins/blue-ridge"
6 | end
7 |
8 | def self.rhino_command
9 | "java -Dblue.ridge.prefix=\"#{plugin_prefix}\" -jar #{plugin_prefix}/lib/js.jar -w -debug"
10 | end
11 |
12 | def self.test_runner_command
13 | "#{rhino_command} #{plugin_prefix}/lib/test_runner.js"
14 | end
15 |
16 | def self.find_base_spec_dir
17 | return "examples" if File.exist?("examples")
18 | return "spec" if File.exist?("spec")
19 | "test"
20 | end
21 |
22 | def self.javascript_spec_dir
23 | base_spec_dir = find_base_spec_dir
24 | return "test/javascript" if base_spec_dir == "test"
25 | base_spec_dir + "/javascripts"
26 | end
27 |
28 | def self.find_javascript_spec_dir
29 | JavaScriptSpecDirs.find {|d| File.exist?(d) }
30 | end
31 |
32 | def self.find_specs_under_current_dir
33 | Dir.glob("*_spec.js")
34 | end
35 |
36 | def self.run_spec(spec_filename)
37 | system("#{test_runner_command} #{spec_filename}")
38 | end
39 |
40 | def self.run_specs_in_dir(spec_dir, spec_name = nil)
41 | result = nil
42 | Dir.chdir(spec_dir) { result = run_specs(spec_name) }
43 | result
44 | end
45 |
46 | def self.run_specs(spec_name = nil)
47 | specs = spec_name.nil? ? find_specs_under_current_dir : ["#{spec_name}_spec.js"]
48 | all_fine = specs.inject(true) {|result, spec| result &= run_spec(spec) }
49 | end
50 | end
51 |
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/lib/consoleReportForRake.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | var failedSpecs = [],
3 | ESC = String.fromCharCode(27),
4 | GREEN = ESC + "[32m",
5 | RED = ESC + "[31m",
6 | RESET = ESC + "[0m",
7 |
8 | // change it to false if your text output doesn't support colouring
9 | coloured = true;
10 |
11 | function printGreen(message){
12 | if(coloured) { message = GREEN + message + RESET; }
13 | print(message);
14 | }
15 |
16 | function printRed(message){
17 | if(coloured) { message = RED + message + RESET; }
18 | print(message);
19 | }
20 |
21 | $(Screw).bind("before", function(){
22 | var currentContext = "";
23 |
24 | function context_name(element){
25 | var context_name = "";
26 | $(element).parents(".describe").children("h1").each(function(){
27 | context_name = $(this).text() + " " + context_name;
28 | });
29 | return context_name.replace(/^\s+|\s+$/g, '');
30 | }
31 |
32 | function example_name(element){
33 | return $(element).children("h2").text();
34 | }
35 |
36 | function updateContext(context){
37 | if(context != currentContext){
38 | currentContext = context;
39 | print("\n" + context);
40 | }
41 | };
42 |
43 | function report(example, failReason){
44 | var failed = typeof failReason != 'undefined',
45 | context = context_name(example),
46 | example = example_name(example),
47 | print = failed ? printRed : printGreen,
48 | message = " - " + example;
49 | if (failed) {
50 | message += " (FAILED - " + (failedSpecs.length+1) + ")";
51 | failedSpecs.push([context, example, failReason])
52 | }
53 | updateContext(context);
54 | print(message);
55 | }
56 |
57 | $('.it')
58 | .bind('passed', function(){
59 | report(this);
60 | })
61 | .bind('failed', function(e, reason){
62 | report(this, reason);
63 | });
64 | });
65 |
66 | $(Screw).bind("after", function(){
67 | var testCount = $('.passed').length + $('.failed').length;
68 | var failures = $('.failed').length;
69 | var elapsedTime = ((new Date() - Screw.suite_start_time)/1000.0);
70 |
71 | print("\n")
72 | $.each(failedSpecs, function(i, fail){
73 | printRed((i+1) + ")");
74 | printRed(fail[0] + " " + fail[1] + " FAILED:")
75 | printRed(" " + fail[2] + "\n");
76 | });
77 | print(testCount + ' test(s), ' + failures + ' failure(s)');
78 | print(elapsedTime.toString() + " seconds elapsed");
79 |
80 | if(failures > 0) { java.lang.System.exit(1) };
81 | });
82 | })(jQuery);
83 |
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/lib/jquery.fn.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | $.fn.fn = function() {
3 | var self = this;
4 | var extension = arguments[0], name = arguments[0];
5 | if (typeof name == "string") {
6 | return apply(self, name, $.makeArray(arguments).slice(1, arguments.length));
7 | } else {
8 | $.each(extension, function(key, value) {
9 | define(self, key, value);
10 | });
11 | return self;
12 | }
13 | }
14 | function define(self, name, fn) {
15 | self.data(namespacedName(name), fn);
16 | };
17 | function apply(self, name, args) {
18 | var result;
19 | self.each(function(i, item) {
20 | var fn = $(item).data(namespacedName(name));
21 | if (fn) result = fn.apply(item, args)
22 | else throw(name + " is not defined");
23 | });
24 | return result;
25 | };
26 | function namespacedName(name) {
27 | return 'fn.' + name;
28 | }
29 | })(jQuery);
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/lib/js.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/WTTechLabs/taskboard/a5eab7fca0a3f80267e7c7637a59ea977daf78c0/vendor/plugins/blue-ridge/lib/js.jar
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/lib/screw.behaviors.js:
--------------------------------------------------------------------------------
1 | (function($) {
2 | $(Screw).bind('loaded', function() {
3 | $('.status').fn({
4 | display: function() {
5 | $(this).html(
6 | $('.passed').length + $('.failed').length + ' test(s), ' + $('.failed').length + ' failure(s) ' +
7 | ((new Date() - Screw.suite_start_time)/1000.0).toString() + " seconds elapsed"
8 | );
9 | }
10 | });
11 |
12 | $('.describe').fn({
13 | parent: function() {
14 | return $(this).parent('.describes').parent('.describe');
15 | },
16 |
17 | run_befores: function() {
18 | $(this).fn('parent').fn('run_befores');
19 | $(this).children('.befores').children('.before').fn('run');
20 | },
21 |
22 | run_afters: function() {
23 | $(this).fn('parent').fn('run_afters');
24 | $(this).children('.afters').children('.after').fn('run');
25 | },
26 |
27 | enqueue: function() {
28 | $(this).children('.its').children('.it').fn('enqueue');
29 | $(this).children('.describes').children('.describe').fn('enqueue');
30 | },
31 |
32 | selector: function() {
33 | return $(this).fn('parent').fn('selector')
34 | + ' > .describes > .describe:eq(' + $(this).parent('.describes').children('.describe').index(this) + ')';
35 | }
36 | });
37 |
38 | $('body > .describe').fn({
39 | selector: function() { return 'body > .describe' }
40 | });
41 |
42 | $('.it').fn({
43 | parent: function() {
44 | return $(this).parent('.its').parent('.describe');
45 | },
46 |
47 | run: function() {
48 | try {
49 | try {
50 | $(this).fn('parent').fn('run_befores');
51 | $(this).data('screwunit.run')();
52 | } finally {
53 | $(this).fn('parent').fn('run_afters');
54 | }
55 | $(this).trigger('passed');
56 | } catch(e) {
57 | $(this).trigger('failed', [e]);
58 | }
59 | },
60 |
61 | enqueue: function() {
62 | var self = $(this).trigger('enqueued');
63 | $(Screw)
64 | .queue(function() {
65 | self.fn('run');
66 | setTimeout(function() { $(Screw).dequeue() }, 0);
67 | });
68 | },
69 |
70 | selector: function() {
71 | return $(this).fn('parent').fn('selector')
72 | + ' > .its > .it:eq(' + $(this).parent('.its').children('.it').index(this) + ')';
73 | }
74 | });
75 |
76 | $('.before').fn({
77 | run: function() { $(this).data('screwunit.run')() }
78 | });
79 |
80 | $('.after').fn({
81 | run: function() { $(this).data('screwunit.run')() }
82 | });
83 |
84 | $(Screw).trigger('before');
85 | var to_run = unescape(location.search.slice(1)) || 'body > .describe > .describes > .describe';
86 | $(to_run)
87 | .focus()
88 | .eq(0).trigger('scroll').end()
89 | .fn('enqueue');
90 | $(Screw).queue(function() { $(Screw).trigger('after') });
91 | })
92 | })(jQuery);
93 |
--------------------------------------------------------------------------------
/vendor/plugins/blue-ridge/lib/screw.builder.js:
--------------------------------------------------------------------------------
1 | var Screw = (function($) {
2 | var screw = {
3 | Unit: function(fn) {
4 | var contents = fn.toString().match(/^[^\{]*{((.*\n*)*)}/m)[1];
5 | var fn = new Function("matchers", "specifications",
6 | "with (specifications) { with (matchers) { " + contents + " } }"
7 | );
8 |
9 | $(Screw).queue(function() {
10 | Screw.Specifications.context.push($('body > .describe'));
11 | fn.call(this, Screw.Matchers, Screw.Specifications);
12 | Screw.Specifications.context.pop();
13 | $(this).dequeue();
14 | });
15 | },
16 |
17 | Specifications: {
18 | context: [],
19 |
20 | describe: function(name, fn) {
21 | var describe = $('')
22 | .append($('').text(name))
23 | .append('')
24 | .append('