yhara-ticketmap 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/.gitmodules +3 -0
- data/MANIFEST +29 -0
- data/README.rdoc +20 -0
- data/Rakefile +52 -0
- data/TODO +82 -0
- data/VERSION +1 -0
- data/controller/config.rb +9 -0
- data/controller/init.rb +7 -0
- data/controller/main.rb +11 -0
- data/controller/tickets.rb +49 -0
- data/db/migrate/001_create_tickets.rb +14 -0
- data/db/migrate/002_add_deleted_to_tickets.rb +13 -0
- data/db/migrate/003_add_timeouted_to_tickets.rb +13 -0
- data/main.rb +40 -0
- data/model/init.rb +32 -0
- data/model/ticket.rb +49 -0
- data/public/biwascheme/lib/biwascheme.js +106 -0
- data/public/biwascheme/lib/dumper.js +192 -0
- data/public/biwascheme/lib/extra_lib.js +534 -0
- data/public/biwascheme/lib/io.js +326 -0
- data/public/biwascheme/lib/prototype.js +4320 -0
- data/public/biwascheme/lib/r6rs_lib.js +2439 -0
- data/public/biwascheme/lib/stackbase.js +1697 -0
- data/public/biwascheme/lib/webscheme_lib.js +809 -0
- data/public/js/builder.js +136 -0
- data/public/js/controls.js +965 -0
- data/public/js/dragdrop.js +975 -0
- data/public/js/effects.js +1130 -0
- data/public/js/scriptaculous.js +60 -0
- data/public/js/slider.js +275 -0
- data/public/js/sound.js +55 -0
- data/public/js/unittest.js +568 -0
- data/public/scm/board.scm +23 -0
- data/public/scm/hand.scm +48 -0
- data/public/scm/main.scm +69 -0
- data/public/scm/server.scm +30 -0
- data/public/scm/ticket.scm +44 -0
- data/spec/config.rb +13 -0
- data/spec/helper.rb +2 -0
- data/spec/main.rb +13 -0
- data/spec/models.rb +34 -0
- data/spec/tickets.rb +65 -0
- data/ticketmap.gemspec +96 -0
- data/view/index.xhtml +63 -0
- data/view/track.xhtml +29 -0
- metadata +131 -0
data/.gitignore
ADDED
data/.gitmodules
ADDED
data/MANIFEST
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
README.rdoc
|
2
|
+
TODO
|
3
|
+
bin/tickets-server
|
4
|
+
db/migrate/001_create_tickets.rb
|
5
|
+
db/migrate/002_add_deleted_to_tickets.rb
|
6
|
+
db/migrate/003_add_timeouted_to_tickets.rb
|
7
|
+
dot.tickets.conf.sample
|
8
|
+
model/ticket.rb
|
9
|
+
public/biwascheme/MIT-LICENSE.txt
|
10
|
+
public/biwascheme/README
|
11
|
+
public/biwascheme/lib/biwascheme.js
|
12
|
+
public/biwascheme/lib/extra_lib.js
|
13
|
+
public/biwascheme/lib/io.js
|
14
|
+
public/biwascheme/lib/prototype.js
|
15
|
+
public/biwascheme/lib/r6rs_lib.js
|
16
|
+
public/biwascheme/lib/stackbase.js
|
17
|
+
public/biwascheme/lib/webscheme_lib.js
|
18
|
+
public/js/builder.js
|
19
|
+
public/js/controls.js
|
20
|
+
public/js/dragdrop.js
|
21
|
+
public/js/effects.js
|
22
|
+
public/js/scriptaculous.js
|
23
|
+
public/js/slider.js
|
24
|
+
public/js/sound.js
|
25
|
+
public/js/unittest.js
|
26
|
+
public/scm/main.scm
|
27
|
+
public/scm/ticket.scm
|
28
|
+
tickets.gemspec
|
29
|
+
view/index.xhtml
|
data/README.rdoc
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
= tickets
|
2
|
+
|
3
|
+
Two-dimentional TODO manager.
|
4
|
+
|
5
|
+
== Install
|
6
|
+
|
7
|
+
gem install ramaze sequel sqlite3-ruby
|
8
|
+
gem install yhara-tickets
|
9
|
+
|
10
|
+
== Execute
|
11
|
+
|
12
|
+
tickets-server
|
13
|
+
|
14
|
+
then open http://localhost:7007/ in your browser.
|
15
|
+
|
16
|
+
in default, ~/.tickets.db is created to save tickets data.
|
17
|
+
|
18
|
+
== Configuration
|
19
|
+
|
20
|
+
write ~/.tickets.conf (see dot.tickets.conf.sample)
|
data/Rakefile
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
PROJECT_NAME = "ticketmap"
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'jeweler'
|
5
|
+
rescue LoadError
|
6
|
+
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
7
|
+
end
|
8
|
+
|
9
|
+
Jeweler::Tasks.new do |gemspec|
|
10
|
+
gemspec.name = "#{PROJECT_NAME}"
|
11
|
+
gemspec.summary = "Two-dimentional ToDo manager"
|
12
|
+
gemspec.email = "yutaka.hara/at/gmail.com"
|
13
|
+
gemspec.homepage = "http://github.com/yhara/#{PROJECT_NAME}"
|
14
|
+
gemspec.description = gemspec.summary
|
15
|
+
gemspec.authors = ["Yutaka HARA"]
|
16
|
+
gemspec.add_dependency('ramaze', '= 2009.06.12')
|
17
|
+
gemspec.add_dependency('dm-core')
|
18
|
+
gemspec.add_dependency('do_sqlite3')
|
19
|
+
gemspec.files.concat Dir["public/biwascheme/lib/*"]
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "install current source as gem"
|
23
|
+
task :dogfood => [:gemspec, :build] do
|
24
|
+
sh "sudo gem install pkg/#{PROJECT_NAME}-#{File.read("VERSION").chomp}.gem"
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "uninstall the installed gem"
|
28
|
+
task :undogfood do
|
29
|
+
sh "sudo gem uninstall #{PROJECT_NAME}"
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "uninstall, then install current source as gem"
|
33
|
+
task :redogfood => [:undogfood, :dogfood]
|
34
|
+
|
35
|
+
desc "uninstall temporary gem and install from github"
|
36
|
+
task :nodogfood do
|
37
|
+
sh "sudo gem uninstall #{PROJECT_NAME}"
|
38
|
+
sh "sudo gem install yhara-#{PROJECT_NAME}"
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "check for gem to be built"
|
42
|
+
task :stalk do
|
43
|
+
sh "gemstalk yhara #{PROJECT_NAME}"
|
44
|
+
end
|
45
|
+
|
46
|
+
desc "test all"
|
47
|
+
task "spec" do
|
48
|
+
sh "bacon spec/models.rb"
|
49
|
+
sh "bacon spec/main.rb"
|
50
|
+
sh "bacon spec/config.rb"
|
51
|
+
sh "bacon spec/tickets.rb"
|
52
|
+
end
|
data/TODO
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
= How to release
|
2
|
+
|
3
|
+
* (edit TODO)
|
4
|
+
* edit VERSION in bin/tickets-server
|
5
|
+
* rtask -> update version
|
6
|
+
* build gem test
|
7
|
+
* Then, push it!
|
8
|
+
|
9
|
+
= before 1.x.x
|
10
|
+
|
11
|
+
- write server tests
|
12
|
+
- write client tests
|
13
|
+
- when origin is clicked
|
14
|
+
- new ticket appears on the filed
|
15
|
+
- request: /tickets/create
|
16
|
+
- when a ticket is clicked
|
17
|
+
- ticket info is shown in the hand
|
18
|
+
- when a ticket is moved
|
19
|
+
- request: /tickets/move? id, x, y
|
20
|
+
- when ticket title is cliced
|
21
|
+
- show ticket form
|
22
|
+
- when ok is clicked
|
23
|
+
- show new title in the hand
|
24
|
+
- show new title in the field
|
25
|
+
- request: /tickets/rename? id, new
|
26
|
+
- when delete button is clicked
|
27
|
+
- ask really delete the ticket
|
28
|
+
- when Y is clicked
|
29
|
+
- remove the ticket from the field
|
30
|
+
- clear the hand
|
31
|
+
- request: /tickets/delete? id
|
32
|
+
- when N is clicked
|
33
|
+
- do not remove the ticket from the field
|
34
|
+
- keep the hand
|
35
|
+
- no request
|
36
|
+
|
37
|
+
- refactor scheme code (use hashtable as object)
|
38
|
+
|
39
|
+
= before 0.4.0
|
40
|
+
|
41
|
+
- implement tags
|
42
|
+
- different color
|
43
|
+
- show certain tag only
|
44
|
+
- tag 'Done' means fixed tags
|
45
|
+
|
46
|
+
= before 0.3.0
|
47
|
+
|
48
|
+
- change orm to datamapper(or ActiveRecord?)
|
49
|
+
- memorize date when a ticket is created
|
50
|
+
- memorize date when a ticket is deleted
|
51
|
+
|
52
|
+
= before 0.2.0
|
53
|
+
|
54
|
+
- edit ticket body
|
55
|
+
|
56
|
+
= before 0.1.1
|
57
|
+
|
58
|
+
- stick to board edge
|
59
|
+
|
60
|
+
= before 0.1.0.2
|
61
|
+
|
62
|
+
- fix track?
|
63
|
+
+ fix ticket position when generated
|
64
|
+
+ fix move position
|
65
|
+
|
66
|
+
= 0.1.0.1
|
67
|
+
|
68
|
+
+ add Tickets::VERSION
|
69
|
+
|
70
|
+
+ Make it work with gem
|
71
|
+
|
72
|
+
+ fix ticket positions (center=0,0)
|
73
|
+
+ show deleted tickets (including timeouted ones)
|
74
|
+
+ automatically move tickets
|
75
|
+
|
76
|
+
+ Make it installable :-)
|
77
|
+
+ write gemspec (with rtask)
|
78
|
+
+ dependency (ramaze)
|
79
|
+
+ automatic migration in start.rb
|
80
|
+
+ save database on ~/.tickets.db
|
81
|
+
+ move executable to bin/
|
82
|
+
+ command line option (port, db)
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.1
|
data/controller/init.rb
ADDED
data/controller/main.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
class TicketsController < Controller
|
2
|
+
map '/tickets'
|
3
|
+
|
4
|
+
def create
|
5
|
+
ticket = Ticket.new
|
6
|
+
ticket.save
|
7
|
+
|
8
|
+
"(#t . (id . #{ticket.id}))"
|
9
|
+
end
|
10
|
+
|
11
|
+
def list
|
12
|
+
tickets = Ticket.all(:deleted => false)
|
13
|
+
|
14
|
+
'(#t . (' +
|
15
|
+
tickets.map{|ticket|
|
16
|
+
"(#{ticket.id} #{ticket.title.inspect} #{ticket.emergency} #{ticket.importance})"
|
17
|
+
}.join(' ') +
|
18
|
+
'))'
|
19
|
+
end
|
20
|
+
|
21
|
+
def move
|
22
|
+
raise "must be via POST" unless request.post?
|
23
|
+
ticket = Ticket.get(request["id"])
|
24
|
+
raise "ticket not found" unless ticket
|
25
|
+
|
26
|
+
ticket.update_attributes(:emergency => request["x"],
|
27
|
+
:importance => request["y"])
|
28
|
+
"(#t)"
|
29
|
+
end
|
30
|
+
|
31
|
+
def rename
|
32
|
+
raise "must be via POST" unless request.post?
|
33
|
+
ticket = Ticket.get(request["id"])
|
34
|
+
raise "ticket not found" unless ticket
|
35
|
+
|
36
|
+
ticket.update_attributes(:title => request["title"])
|
37
|
+
"(#t)"
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete
|
41
|
+
raise "must be via POST" unless request.post?
|
42
|
+
ticket = Ticket.get(request["id"])
|
43
|
+
raise "ticket not found" unless ticket
|
44
|
+
|
45
|
+
ticket.update_attributes(:deleted => true)
|
46
|
+
"(#t)"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateTickets < Sequel::Migration
|
2
|
+
def up
|
3
|
+
create_table :tickets do
|
4
|
+
primary_key :id
|
5
|
+
integer :importance, :null => false, :default => 0
|
6
|
+
integer :emergency, :null => false, :default => 0
|
7
|
+
string :title, :null => false, :default => ""
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def down
|
12
|
+
drop_table :tickets
|
13
|
+
end
|
14
|
+
end
|
data/main.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'optparse'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'ruby-station'; RubyStation.parse_argv
|
5
|
+
require 'ramaze'
|
6
|
+
|
7
|
+
module TicketMap
|
8
|
+
include Innate::Optioned
|
9
|
+
VERSION = File.read(__DIR__("VERSION"))
|
10
|
+
|
11
|
+
options.dsl do
|
12
|
+
o "Path of config file",
|
13
|
+
:config, File.expand_path("~/.ticketmap.rb")
|
14
|
+
# o "Path of database file",
|
15
|
+
# :db, File.expand_path("~/.ticketmap.db")
|
16
|
+
# o "Port number",
|
17
|
+
# :port, 7007
|
18
|
+
o "Interval to automatically move tickets (hours)",
|
19
|
+
:shake_interval, 24
|
20
|
+
o "Distance to automatically move tickets (pixels)",
|
21
|
+
:shake_distance, 8
|
22
|
+
o "Width of the board (pixels)",
|
23
|
+
:board_width, 600
|
24
|
+
o "Height of the board (pixels)",
|
25
|
+
:board_height, 600
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
$LOAD_PATH.unshift __DIR__("./")
|
30
|
+
require 'controller/init.rb'
|
31
|
+
require 'model/init.rb'
|
32
|
+
|
33
|
+
conf = TicketMap.options[:config]
|
34
|
+
if File.exist?(conf)
|
35
|
+
Ramaze::Log.info("Loading config file: #{conf}")
|
36
|
+
load conf
|
37
|
+
end
|
38
|
+
|
39
|
+
Ramaze.start :port => RubyStation.port,
|
40
|
+
:root => __DIR__('./')
|
data/model/init.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'dm-core'
|
2
|
+
require 'dm-validations'
|
3
|
+
require 'dm-aggregates' # needed for #count in spec
|
4
|
+
db_path = RubyStation.data_path('ticketmap.db')
|
5
|
+
DataMapper.setup(:default, "sqlite3://#{db_path}")
|
6
|
+
|
7
|
+
require __DIR__('./ticket.rb')
|
8
|
+
|
9
|
+
DataMapper.auto_upgrade!
|
10
|
+
|
11
|
+
#
|
12
|
+
# ramaze paginate for datamapper
|
13
|
+
#
|
14
|
+
require 'ramaze/helper/paginate'
|
15
|
+
class DataMapper::Collection
|
16
|
+
def paginate(page, limit)
|
17
|
+
DMCollectionPager.new(self, page, limit)
|
18
|
+
end
|
19
|
+
|
20
|
+
class DMCollectionPager < Ramaze::Helper::Paginate::Paginator::ArrayPager
|
21
|
+
def each(&block)
|
22
|
+
from = ((@page - 1) * @limit)
|
23
|
+
from = 0 if from < 0
|
24
|
+
to = from + @limit
|
25
|
+
|
26
|
+
a = @array[from...to] || []
|
27
|
+
a.each(&block)
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
data/model/ticket.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
class Ticket
|
2
|
+
include DataMapper::Resource
|
3
|
+
|
4
|
+
# properties
|
5
|
+
|
6
|
+
property :id, Serial
|
7
|
+
property :importance, Integer
|
8
|
+
property :emergency, Integer
|
9
|
+
property :title, String
|
10
|
+
property :deleted, Boolean
|
11
|
+
property :timeouted, Boolean
|
12
|
+
|
13
|
+
# validations
|
14
|
+
|
15
|
+
before :save do
|
16
|
+
self.importance ||= 0
|
17
|
+
self.emergency ||= 0
|
18
|
+
self.title ||= ""
|
19
|
+
self.deleted = false if self.deleted == nil
|
20
|
+
self.timeouted = false if self.timeouted == nil
|
21
|
+
end
|
22
|
+
|
23
|
+
# class methods
|
24
|
+
|
25
|
+
@@last_shook = Time.now
|
26
|
+
|
27
|
+
def self.needs_shaking?
|
28
|
+
(Time.now - @@last_shook) > TicketMap.options[:shake_interval]*60*60
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.shake!
|
32
|
+
Ticket.all.each do |ticket|
|
33
|
+
pos = ticket.emergency
|
34
|
+
dir = (ticket.importance < 0 ? 1 : -1)
|
35
|
+
newpos = pos + TicketMap.options[:shake_distance] * dir
|
36
|
+
if newpos > (TicketMap.options[:board_width] / 2)
|
37
|
+
newpos = (TicketMap.options[:board_width] / 2)
|
38
|
+
end
|
39
|
+
|
40
|
+
ticket.emergency = newpos if newpos != pos
|
41
|
+
if newpos < -(TicketMap.options[:board_width] / 2)
|
42
|
+
ticket.deleted = true
|
43
|
+
ticket.timeouted = true
|
44
|
+
end
|
45
|
+
ticket.save
|
46
|
+
end
|
47
|
+
@@last_shook = Time.now
|
48
|
+
end
|
49
|
+
end
|