rtt 0.0.0.47 → 0.0.0.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Gemfile CHANGED
@@ -3,19 +3,16 @@ source 'http://gems.github.com'
3
3
 
4
4
  gem 'echoe'
5
5
  gem 'highline', '1.5.2'
6
- gem 'activesupport', ['>= 2.3.5', '<= 2.3.8']
6
+ gem 'activesupport', '3.2.6'
7
7
  gem 'prawn', '0.8.4'
8
- gem 'data_objects', '0.10.2'
9
- gem 'dm-core', '1.0.0'
10
- gem 'dm-validations', '1.0.0'
11
- gem 'dm-migrations', '1.0.0'
12
- gem 'dm-sqlite-adapter', '1.0.0'
8
+ gem 'activerecord', '3.2.6'
9
+ gem 'sqlite3'
13
10
  gem 'rake', '0.8.2'
14
11
  gem 'gemcutter', '0.7.1'
15
12
 
16
13
  group :development do
14
+ gem 'debugger'
17
15
  gem 'rspec', '1.3.0'
18
16
  gem 'mocha'
19
17
  gem 'hanna'
20
- gem 'ruby-debug'
21
18
  end
data/Gemfile.lock CHANGED
@@ -2,32 +2,32 @@ GEM
2
2
  remote: http://rubygems.org/
3
3
  remote: http://gems.github.com/
4
4
  specs:
5
- activesupport (2.3.8)
6
- addressable (2.2.7)
5
+ activemodel (3.2.6)
6
+ activesupport (= 3.2.6)
7
+ builder (~> 3.0.0)
8
+ activerecord (3.2.6)
9
+ activemodel (= 3.2.6)
10
+ activesupport (= 3.2.6)
11
+ arel (~> 3.0.2)
12
+ tzinfo (~> 0.3.29)
13
+ activesupport (3.2.6)
14
+ i18n (~> 0.6)
15
+ multi_json (~> 1.0)
7
16
  allison (2.0.3)
17
+ arel (3.0.2)
18
+ builder (3.0.0)
8
19
  columnize (0.3.6)
9
- data_objects (0.10.2)
10
- addressable (~> 2.1)
11
- dm-core (1.0.0)
12
- addressable (~> 2.1)
13
- extlib (~> 0.9.15)
14
- dm-do-adapter (1.0.0)
15
- data_objects (~> 0.10.1)
16
- dm-core (~> 1.0.0)
17
- dm-migrations (1.0.0)
18
- dm-core (~> 1.0.0)
19
- dm-sqlite-adapter (1.0.0)
20
- dm-do-adapter (~> 1.0.0)
21
- do_sqlite3 (~> 0.10.2)
22
- dm-validations (1.0.0)
23
- dm-core (~> 1.0.0)
24
- do_sqlite3 (0.10.2)
25
- data_objects (= 0.10.2)
20
+ debugger (1.2.0)
21
+ columnize (>= 0.3.1)
22
+ debugger-linecache (~> 1.1.1)
23
+ debugger-ruby_core_source (~> 1.1.3)
24
+ debugger-linecache (1.1.2)
25
+ debugger-ruby_core_source (>= 1.1.1)
26
+ debugger-ruby_core_source (1.1.3)
26
27
  echoe (4.5.6)
27
28
  allison
28
29
  gemcutter
29
30
  rubyforge
30
- extlib (0.9.15)
31
31
  gemcutter (0.7.1)
32
32
  haml (2.2.24)
33
33
  hanna (0.1.12)
@@ -35,12 +35,12 @@ GEM
35
35
  rake (~> 0.8.2)
36
36
  rdoc (~> 2.3.0)
37
37
  highline (1.5.2)
38
+ i18n (0.6.0)
38
39
  json_pure (1.6.5)
39
- linecache (0.46)
40
- rbx-require-relative (> 0.0.4)
41
40
  metaclass (0.0.1)
42
41
  mocha (0.10.4)
43
42
  metaclass (~> 0.0.1)
43
+ multi_json (1.3.6)
44
44
  prawn (0.8.4)
45
45
  prawn-core (>= 0.8.4, < 0.9)
46
46
  prawn-layout (>= 0.8.4, < 0.9)
@@ -49,27 +49,20 @@ GEM
49
49
  prawn-layout (0.8.4)
50
50
  prawn-security (0.8.4)
51
51
  rake (0.8.2)
52
- rbx-require-relative (0.0.5)
53
52
  rdoc (2.3.0)
54
53
  rspec (1.3.0)
55
- ruby-debug (0.10.4)
56
- columnize (>= 0.1)
57
- ruby-debug-base (~> 0.10.4.0)
58
- ruby-debug-base (0.10.4)
59
- linecache (>= 0.3)
60
54
  rubyforge (2.0.4)
61
55
  json_pure (>= 1.1.7)
56
+ sqlite3 (1.3.6)
57
+ tzinfo (0.3.33)
62
58
 
63
59
  PLATFORMS
64
60
  ruby
65
61
 
66
62
  DEPENDENCIES
67
- activesupport (>= 2.3.5, <= 2.3.8)
68
- data_objects (= 0.10.2)
69
- dm-core (= 1.0.0)
70
- dm-migrations (= 1.0.0)
71
- dm-sqlite-adapter (= 1.0.0)
72
- dm-validations (= 1.0.0)
63
+ activerecord (= 3.2.6)
64
+ activesupport (= 3.2.6)
65
+ debugger
73
66
  echoe
74
67
  gemcutter (= 0.7.1)
75
68
  hanna
@@ -78,4 +71,4 @@ DEPENDENCIES
78
71
  prawn (= 0.8.4)
79
72
  rake (= 0.8.2)
80
73
  rspec (= 1.3.0)
81
- ruby-debug
74
+ sqlite3
data/Manifest CHANGED
@@ -6,25 +6,25 @@ README.rdoc
6
6
  Rakefile
7
7
  USAGE.txt
8
8
  bin/rtt
9
- db/rtt.sqlite3
9
+ db/config.yml
10
+ db/schema.rb
10
11
  db/test.sqlite3
12
+ lib/extensions/array.rb
13
+ lib/extensions/date.rb
14
+ lib/extensions/hash.rb
15
+ lib/extensions/kernel.rb
16
+ lib/models/client.rb
17
+ lib/models/project.rb
18
+ lib/models/task.rb
19
+ lib/models/user.rb
11
20
  lib/rtt.rb
12
- lib/rtt/array_extensions.rb
13
21
  lib/rtt/boot.rb
14
- lib/rtt/client.rb
15
22
  lib/rtt/cmd_line_parser.rb
16
- lib/rtt/hash_extensions.rb
17
23
  lib/rtt/interactive_configurator.rb
18
- lib/rtt/project.rb
19
24
  lib/rtt/query_builder.rb
20
25
  lib/rtt/report_generator.rb
21
26
  lib/rtt/storage.rb
22
- lib/rtt/system_extensions.rb
23
- lib/rtt/task.rb
24
- lib/rtt/user.rb
25
- log/rtt.sqlite3
26
- rtt.gemspec
27
- spec/datamapper_spec_helper.rb
28
- spec/lib/rtt/task_spec.rb
27
+ spec/ar_spec_helper.rb
28
+ spec/lib/models/task_spec.rb
29
29
  spec/lib/rtt_spec.rb
30
30
  tasks/rtt.rake
data/Rakefile CHANGED
@@ -3,15 +3,15 @@ require 'echoe'
3
3
 
4
4
  # PACKAGING ============================================================
5
5
 
6
- Echoe.new('rtt', '0.0.0.47') do |p|
6
+ Echoe.new('rtt', '0.0.0.48') do |p|
7
7
  p.description = 'RTT is a tool for tracking time'
8
8
  p.url = 'http://github.com/marklazz/rtt'
9
9
  p.author = 'Marcelo Giorgi'
10
10
  p.email = 'marklazz.uy@gmail.com'
11
11
  p.ignore_pattern = [ 'tmp/*', 'script/*', '*.sh' ]
12
12
  p.runtime_dependencies = [
13
- ['highline', "1.5.2"], ['activesupport', '>= 2.3.5', '<= 2.3.8'], ['prawn', '0.8.4'], ['dm-core', '1.0.0'], [ 'dm-validations', '1.0.0'], [ 'dm-migrations', '1.0.0'], ['dm-sqlite-adapter', '1.0.0'], [ 'rake', '0.8.2' ], [ 'addressable', '2.2.7' ],
14
- [ 'allison', '2.0.3'], [ 'data_objects', '0.10.2' ], [ 'extlib', '0.9.15' ], [ 'json_pure', '1.6.5' ], [ 'prawn-core', '0.8.4' ], [ 'prawn-layout', '0.8.4'], ['prawn-security', '0.8.4'], ['haml', '2.2.24'], ['hanna', '0.1.12'], ['metaclass', '0.0.1'],
13
+ ['highline', "1.5.2"], ['activerecord', '3.2.6'], ['activesupport', '3.2.6'], ['prawn', '0.8.4'], [ 'rake', '0.8.2' ],
14
+ [ 'allison', '2.0.3'], [ 'extlib', '0.9.15' ], [ 'json_pure', '1.6.5' ], [ 'prawn-core', '0.8.4' ], [ 'prawn-layout', '0.8.4'], ['prawn-security', '0.8.4'], ['haml', '2.2.24'], ['hanna', '0.1.12'], ['metaclass', '0.0.1'],
15
15
  ['rspec', '1.3.0' ], ['mocha', '0.10.4'], ['rubyforge', '2.0.4'], ['rdoc', '2.3.0'], [ 'gemcutter', '0.7.1'], ['echoe', '4.5.6']
16
16
  ]
17
17
  p.development_dependencies = [ ]
data/bin/rtt CHANGED
@@ -2,9 +2,9 @@
2
2
  # The command line Haml parser.
3
3
  $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
4
4
 
5
- require 'rtt/system_extensions'
5
+ require 'extensions/kernel'
6
6
  with_warnings_suppressed do
7
- require 'rtt'
7
+ require 'rtt'
8
8
  Rtt.init
9
9
  command = Rtt.capture(ARGV)
10
10
  Rtt.execute(command)
data/db/config.yml ADDED
@@ -0,0 +1,10 @@
1
+ production:
2
+ adapter: sqlite3
3
+ database: db/production.sqlite3
4
+ pool: 5
5
+ timeout: 5000
6
+ test:
7
+ adapter: sqlite3
8
+ database: db/test.sqlite3
9
+ pool: 5
10
+ timeout: 5000
data/db/schema.rb ADDED
@@ -0,0 +1,43 @@
1
+ ActiveRecord::Schema.define :version => 0 do
2
+
3
+ create_table :clients, :force => true do |t|
4
+ t.string :name, :default => Client::DEFAULT_NAME
5
+ t.string :description, :default => Client::DEFAULT_DESCRIPTION
6
+ t.boolean :active, :default => false
7
+ end
8
+
9
+ create_table :projects, :force => true do |t|
10
+ t.string :name, :default => Project::DEFAULT_NAME
11
+ t.string :description, :default => Project::DEFAULT_DESCRIPTION
12
+ t.boolean :active, :default => false
13
+ t.float :rate
14
+ t.integer :client_id
15
+ end
16
+
17
+ create_table :tasks, :force => true do |t|
18
+ t.string :name
19
+ t.date :date
20
+ t.boolean :active, :default => false
21
+ t.datetime :start_at
22
+ t.datetime :end_at
23
+ t.float :accumulated_spent_time, :default => 0
24
+ t.float :rate, :default => 0
25
+ t.integer :user_id
26
+ t.integer :project_id
27
+ end
28
+
29
+ create_table :users, :force => true do |t|
30
+ t.string :nickname
31
+ t.string :first_name
32
+ t.string :last_name
33
+ t.string :company
34
+ t.string :address
35
+ t.string :city
36
+ t.string :country
37
+ t.string :email
38
+ t.string :phone
39
+ t.string :zip
40
+ t.string :site
41
+ t.boolean :active, :default => false
42
+ end
43
+ end
data/db/test.sqlite3 CHANGED
Binary file
@@ -0,0 +1,15 @@
1
+ class Date
2
+
3
+ class << self
4
+ unless method_defined?(:day_fraction_to_time)
5
+ SECONDS_IN_DAY = Rational(1, 86400)
6
+
7
+ def day_fraction_to_time(fr)
8
+ ss, fr = fr.divmod(SECONDS_IN_DAY) # 4p
9
+ h, ss = ss.divmod(3600)
10
+ min, s = ss.divmod(60)
11
+ return h, min, s, fr
12
+ end
13
+ end
14
+ end
15
+ end
File without changes
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env ruby
2
+ class Client < ActiveRecord::Base
3
+
4
+ DEFAULT_NAME = 'default'
5
+ DEFAULT_DESCRIPTION = 'Default Client'
6
+
7
+ has_many :projects
8
+
9
+ before_create do |client|
10
+ client.active = true if Client.all.length == 0
11
+ end
12
+
13
+ def self.default
14
+ first_or_create :active => true
15
+ end
16
+
17
+ def self.current_active?
18
+ where(:active => true).first
19
+ end
20
+
21
+ def activate
22
+ deactivate_all
23
+ self.active = true
24
+ self.save
25
+ self
26
+ end
27
+
28
+ def deactivate_all
29
+ Client.all.each do |client|
30
+ client.active = false
31
+ client.save
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/ruby -w
2
+ class Project < ActiveRecord::Base
3
+
4
+ DEFAULT_NAME = 'default'
5
+ DEFAULT_DESCRIPTION = 'Default Project'
6
+
7
+ has_many :tasks
8
+ has_many :users, :through => :tasks
9
+ belongs_to :client
10
+
11
+ before_validation :set_default_client
12
+
13
+ before_create do |project|
14
+ project.active = true if Project.all.length == 0
15
+ end
16
+
17
+ def self.default
18
+ find_or_create_by_active true
19
+ end
20
+
21
+ def self.current_active?
22
+ where(:active => true).first
23
+ end
24
+
25
+ def activate
26
+ deactivate_all
27
+ self.active = true
28
+ self.save
29
+ self
30
+ end
31
+
32
+ def deactivate_all
33
+ Project.all.each do |project|
34
+ if project.id != self.id
35
+ project.active = false
36
+ project.save
37
+ end
38
+ end
39
+ end
40
+
41
+ def set_default_client
42
+ self.client = Client.default if self.client.nil?
43
+ end
44
+ end
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env ruby
2
+ class Task < ActiveRecord::Base
3
+
4
+ DEFAULT_NAME = 'Default task'
5
+
6
+ belongs_to :project
7
+ has_one :client, :through => :project
8
+ belongs_to :user
9
+
10
+ before_validation :set_default_project
11
+ before_validation :set_default_user
12
+
13
+ def self.task(task_name)
14
+ base_attributes = { :name => task_name, :user_id => Rtt.current_user.id, :date => Date.today, :rate => (Rtt.current_project.rate if Rtt.current_project.present?) }
15
+ if task_name.nil?
16
+ existing_task = Task.where(:active => true).first
17
+ if existing_task
18
+ existing_task
19
+ else
20
+ base_attributes.merge!(:name => DEFAULT_NAME) if task_name.blank?
21
+ Task.create(base_attributes)
22
+ end
23
+ elsif (existing_task = Task.where(base_attributes).where(Task.arel_table[:start_at].gt(Date.today.beginning_of_day)).first).present?
24
+ existing_task
25
+ else
26
+ Task.create(base_attributes)
27
+ end
28
+ end
29
+
30
+ def start
31
+ self.start_at = DateTime.now
32
+ self.active = true
33
+ save
34
+ self
35
+ end
36
+
37
+ def add_current_spent_time_to_accumulated_spent_time
38
+ self.accumulated_spent_time = self.accumulated_spent_time + self.time_difference_since_start_at
39
+ end
40
+
41
+ def clone_task(task)
42
+ task = self.dup
43
+ task.id = nil
44
+ task
45
+ end
46
+
47
+ def duration
48
+ return '-' if end_at.blank?
49
+ convert_to_hour_and_minutes(accumulated_spent_time)
50
+ end
51
+
52
+ def duration=(d)
53
+ return unless !!/^(\d{1,2})[hH]{1,2}(\d{1,2})[mM]{1,2}$/.match(d)
54
+ self.start_at = DateTime.parse('00:00:01', self.date)
55
+ self.end_at = DateTime.parse('00:00:01', self.date).advance(:hours => $1.to_i, :minutes => $2.to_i, :seconds => 1)
56
+ self.accumulated_spent_time = self.time_difference_since_start_at
57
+ end
58
+
59
+ def set_default_project
60
+ self.project = Project.default if self.project.nil?
61
+ end
62
+
63
+ def set_default_user
64
+ self.user = User.default if self.user.nil?
65
+ end
66
+
67
+ def stop
68
+ split_task if span_multiple_days?
69
+ finish
70
+ self
71
+ end
72
+
73
+ def pause
74
+ split_task if span_multiple_days?
75
+ finish(DateTime.now, true)
76
+ self
77
+ end
78
+
79
+ def time_difference_since_start_at
80
+ end_date_or_now = self.end_at ? self.end_at : DateTime.now
81
+ end_date_or_now.to_datetime - self.start_at.to_datetime
82
+ end
83
+
84
+ private
85
+
86
+ def convert_to_hour_and_minutes(dif)
87
+ hours, mins = time_diff_in_hours_and_minutes(dif)
88
+ "#{hours}h#{mins}m"
89
+ end
90
+
91
+ def finish(end_at = DateTime.now, activation = false)
92
+ self.end_at = end_at
93
+ self.date = end_at.to_date
94
+ self.add_current_spent_time_to_accumulated_spent_time
95
+ self.active = activation
96
+ self.save
97
+ end
98
+
99
+ def save_in_between_days_split(date)
100
+ task = clone_task(self)
101
+ task.start_at = date.beginning_of_day
102
+ end_at = date.end_of_day.to_datetime
103
+ task.send(:finish, end_at)
104
+ task.save
105
+ end
106
+
107
+ def save_last_task_split(date)
108
+ task = clone_task(self)
109
+ end_at = date.end_of_day.to_datetime
110
+ task.send(:finish, end_at)
111
+ task.save
112
+ end
113
+
114
+ def span_multiple_days?
115
+ self.start_at.day != Date.today.day
116
+ end
117
+
118
+ def split_task
119
+ date = Date.today - 1
120
+ while (date.to_datetime > self.start_at)
121
+ save_in_between_days_split(date)
122
+ date -= 1
123
+ end
124
+ save_last_task_split(date)
125
+ self.start_at = Date.today.beginning_of_day.to_datetime
126
+ end
127
+
128
+ def time_diff_in_hours_and_minutes(dif)
129
+ Date::day_fraction_to_time(dif)
130
+ end
131
+ end