slimtimer4r 0.2.0

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/History.txt ADDED
@@ -0,0 +1,9 @@
1
+ == 0.2.0 / 2008-01-09
2
+
3
+ * 1 major enhancement
4
+ * Not-so-ugly code thanks to borrowing from the 37 Signals / Basecamp sample Ruby wrappers
5
+
6
+ == 0.1.0 / Sometime back in 2006...
7
+
8
+ * Lots of UGLY code
9
+
data/Manifest.txt ADDED
@@ -0,0 +1,7 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/slimtimer4r
6
+ lib/slimtimer4r.rb
7
+ test/test_slimtimer4r.rb
data/README.txt ADDED
@@ -0,0 +1,51 @@
1
+ == SlimTimer4R
2
+
3
+ == Overview
4
+
5
+ A basic wrapper against the SlimTimer (www.slimtimer.com) API.
6
+
7
+ == Installation
8
+
9
+ RubyGems FTW!
10
+
11
+ sudo gem install slimtimer4r
12
+
13
+ == Usage
14
+
15
+ require 'slimtimer4r'
16
+
17
+ slimtimer = SlimTimer.new("EMAIL", "PASSWORD", "API_KEY")
18
+ tasks = slimtimer.list_tasks
19
+ => [#<Record(Task) "name"=>"Ta...">, #<Record(Task) "name"=>"Br...">...]
20
+
21
+ == Thanks
22
+ - 37 Signals for their sample Backpack/Basecamp Ruby wrappers
23
+
24
+ == Author
25
+ - Dylan Markow (dylan@dylanmarkow.com)
26
+
27
+
28
+ == License
29
+
30
+ (The MIT License)
31
+
32
+ Copyright (c) 2008
33
+
34
+ Permission is hereby granted, free of charge, to any person obtaining
35
+ a copy of this software and associated documentation files (the
36
+ 'Software'), to deal in the Software without restriction, including
37
+ without limitation the rights to use, copy, modify, merge, publish,
38
+ distribute, sublicense, and/or sell copies of the Software, and to
39
+ permit persons to whom the Software is furnished to do so, subject to
40
+ the following conditions:
41
+
42
+ The above copyright notice and this permission notice shall be
43
+ included in all copies or substantial portions of the Software.
44
+
45
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
46
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
47
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
48
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
49
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
50
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
51
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,18 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+ require './lib/slimtimer4r.rb'
6
+
7
+ Hoe.new('slimtimer4r', SlimTimer::VERSION) do |p|
8
+ p.rubyforge_name = 'slimtimer4r'
9
+ p.author = 'Dylan Markow'
10
+ p.email = 'dylan@dylanmarkow.com'
11
+ p.remote_rdoc_dir = ''
12
+ # p.summary = 'FIX'
13
+ # p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
14
+ # p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
15
+ p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
16
+ end
17
+
18
+ # vim: syntax=Ruby
data/bin/slimtimer4r ADDED
File without changes
@@ -0,0 +1,207 @@
1
+ require 'yaml'
2
+ require 'net/http'
3
+
4
+ class SlimTimer
5
+ VERSION = '0.2.0'
6
+
7
+ #
8
+ # The Record class is used to encapsulate the data returned from the SlimTimer API
9
+ class Record
10
+ attr_reader :type, :hash
11
+
12
+ def initialize(type, hash)
13
+ @type = type
14
+ @hash = hash
15
+ end
16
+
17
+ # Checks to see if one of the values of the hash is another hash, and if so, changes it to a Record object. This allows you to use time_entry.task.name instead of time_entry.task["name"]
18
+ def [](name)
19
+ case @hash[name]
20
+ when Hash then
21
+ @hash[name] = (@hash[name].keys.length == 1 && Array === @hash[name].values.first) ? @hash[name].values.first.map { |v| Record.new(@hash[name].keys.first, v) } : Record.new(name, @hash[name])
22
+ else
23
+ @hash[name]
24
+ end
25
+ end
26
+
27
+ def id
28
+ @hash["id"]
29
+ end
30
+
31
+ def attributes
32
+ @hash.keys
33
+ end
34
+
35
+ def respond_to?(sym)
36
+ super || @hash.has_key?(sym)
37
+ end
38
+
39
+ # Used to convert an unknown method into a hash key. For example, item.user_id would become item["user_id"]
40
+ def method_missing(sym, *args)
41
+ if args.empty? && !block_given? && respond_to?(sym.to_s)
42
+ self[sym.to_s]
43
+ else
44
+ super
45
+ end
46
+ end
47
+
48
+ def to_s
49
+ "\#<Record(#{@type}) #{@hash.inspect[1..-2]}>"
50
+ end
51
+
52
+ def inspect
53
+ to_s
54
+ end
55
+
56
+ private
57
+
58
+ def dashify(name)
59
+ name.to_s.tr("_","-")
60
+ end
61
+ end
62
+
63
+ attr_accessor :email, :password, :api_key, :user_id, :access_token, :request
64
+
65
+ # Creates a new SlimTimer object and obtains the +access_token+ and +user_id+ from the SlimTimer API by sending your +email+, +password+, and +api_key+. Raises a _RuntimeError_ if it can't authenticate.
66
+ #
67
+ # slim_timer = SlimTimer.new("person@example.com", "password", "12345")
68
+ # => #<SlimTimer:0x68bca8 @password="password"...>
69
+ #
70
+ # slim_timer = SlimTimer.new("bademail@example.com", "badpassword", "12345")
71
+ # => RuntimeError: Error occurred (500)
72
+ def initialize(email, password, api_key)
73
+ @email, @password, @api_key = email, password, api_key
74
+ connect
75
+ get_token
76
+ end
77
+
78
+ # Returns a list of tasks.
79
+ #
80
+ # Options:
81
+ # <tt>show_completed</tt>:: Include completed tasks. Specify +only+ to only include the completed tasks. Valid options are +yes+, +no+, and +only+. Default is +yes+.
82
+ # <tt>role</tt>:: Include tasks where the user's role is one of the roles given (comma delimited). Valid options include +owner+, +coworker+, and +reporter+. Default is +owner,coworker+.
83
+ def list_tasks(show_completed="yes", role="owner,coworker")
84
+ request("get", "#{@user_id}/tasks?api_key=#{@api_key}&access_token=#{@access_token}&show_completed=#{show_completed}&role=#{role}", "Tasks")
85
+ end
86
+
87
+ # Returns a specific task. Returns _nil_ if the record is not found.
88
+ #
89
+ # Options:
90
+ # <tt>task_id</tt>:: The id of the task you would like to retrieve.
91
+ def show_task(task_id)
92
+ request("get", "#{@user_id}/tasks/#{task_id}?api_key=#{@api_key}&access_token=#{@access_token}", "Task")
93
+ end
94
+
95
+ def delete_task(task_id)
96
+ request("delete", "#{@user_id}/tasks/#{task_id}?api_key=#{@api_key}&access_token=#{@access_token}", "Task")
97
+ end
98
+
99
+ def create_task(name, tags=nil, coworker_emails=nil, reporter_emails=nil, completed_on=nil)
100
+ request("post", "#{@user_id}/tasks", {"access_token" => @access_token, "api_key" => @api_key, "task" => {"name" => name, "tags" => tags, "coworker_emails" => coworker_emails, "reporter_emails" => reporter_emails, "completed_on" => completed_on}}, "Task")
101
+ end
102
+
103
+ def update_task(task_id, name, tags=nil, coworker_emails=nil, reporter_emails=nil, completed_on=nil)
104
+ request("put", "#{@user_id}/tasks/#{task_id}", {"access_token" => @access_token, "api_key" => @api_key, "task" => {"name" => name, "tags" => tags, "coworker_emails" => coworker_emails, "reporter_emails" => reporter_emails, "completed_on" => completed_on}}, "Task")
105
+ end
106
+
107
+ def list_timeentries(range_start=nil, range_end=nil)
108
+ range_start = range_start.strftime("%Y-%m-%dT%H:%M:%SZ") unless range_start.nil?
109
+ range_end = range_end.strftime("%Y-%m-%dT%H:%M:%SZ") unless range_end.nil?
110
+ request("get", "#{@user_id}/time_entries?api_key=#{@api_key}&access_token=#{@access_token}&range_start=#{range_start}&range_end=#{range_end}", "TimeEntries")
111
+ end
112
+
113
+ def update_timeentry(timeentry_id, start_time, duration_in_seconds, task_id, end_time, tags=nil, comments=nil, in_progress=nil)
114
+ start_time = start_time.strftime("%Y-%m-%dT%H:%M:%SZ")
115
+ end_time = end_time.strftime("%Y-%m-%dT%H:%M:%SZ") unless end_time.nil?
116
+
117
+ # add the default params
118
+ params = {
119
+ "start_time" => start_time,
120
+ "duration_in_seconds" => duration_in_seconds,
121
+ "task_id" => task_id,
122
+ "end_time" => end_time,
123
+ }
124
+
125
+ # only add the applicable params
126
+ params.merge!({"tags" => tags}) unless tags.nil?
127
+ params.merge!({"comments" => comments}) unless comments.nil?
128
+ params.merge!({"in_progress" => in_progress}) unless in_progress.nil?
129
+
130
+
131
+ request("put", "#{@user_id}/time_entries/#{timeentry_id}", {"access_token" => @access_token, "api_key" => @api_key, "time_entry" => params}, "TimeEntry")
132
+ end
133
+
134
+ def create_timeentry(start_time, duration_in_seconds, task_id, end_time, tags=nil, comments=nil, in_progress=nil)
135
+ start_time = start_time.strftime("%Y-%m-%dT%H:%M:%SZ")
136
+ end_time = end_time.strftime("%Y-%m-%dT%H:%M:%SZ") unless end_time.nil?
137
+
138
+ # add the default params
139
+ params = {
140
+ "start_time" => start_time,
141
+ "duration_in_seconds" => duration_in_seconds,
142
+ "task_id" => task_id,
143
+ "end_time" => end_time,
144
+ }
145
+
146
+ # only add the applicable params
147
+ params.merge!({"tags" => tags}) unless tags.nil?
148
+ params.merge!({"comments" => comments}) unless comments.nil?
149
+ params.merge!({"in_progress" => in_progress}) unless in_progress.nil?
150
+
151
+
152
+ request("post", "#{@user_id}/time_entries", {"access_token" => @access_token, "api_key" => @api_key, "time_entry" => params}, "TimeEntry")
153
+ end
154
+
155
+ def show_timeentry(timeentry_id)
156
+ request("get", "#{@user_id}/time_entries/#{timeentry_id}?api_key=#{@api_key}&access_token=#{@access_token}", "TimeEntry")
157
+ end
158
+
159
+ def delete_timeentry(timeentry_id)
160
+ request("delete", "#{@user_id}/time_entries/#{timeentry_id}?api_key=#{@api_key}&access_token=#{@access_token}", "TimeEntry")
161
+ end
162
+
163
+
164
+ private
165
+ def get_token
166
+ values = request("post", "token", {"user" => {"email" => @email, "password" => @password}, "api_key" => @api_key})
167
+ @access_token = values.access_token
168
+ @user_id = values.user_id
169
+ end
170
+
171
+ def connect
172
+ @connection = Net::HTTP.new("www.slimtimer.com", 80)
173
+ end
174
+
175
+ def request(method, path, parameters = {}, type="Result")
176
+ method.downcase!
177
+ if !['post','get','delete','put'].include?(method)
178
+ raise "Error: bad method parameter"
179
+ end
180
+ if %w(get delete).include?(method)
181
+ response = @connection.send(method, "/users/#{path}", {"Accept" => "application/x-yaml"})
182
+ else
183
+ response = @connection.send(method, "/users/#{path}", parameters.to_yaml, {"Content-Type" => "application/x-yaml", "Accept" => "application/x-yaml"})
184
+ end
185
+
186
+ if response.code == "200"
187
+
188
+ # If this was a delete request, return true
189
+ if method == 'delete'
190
+ true
191
+ else
192
+ result = YAML::load(response.body)
193
+ if result.is_a?(Array)
194
+ result.map { |row| Record.new(type, row) }
195
+ else
196
+ Record.new(type, result)
197
+ end
198
+ end
199
+ elsif response.code == "404"
200
+ method == 'get' ? nil : false
201
+ else
202
+ raise "Error occurred (#{response.code}): #{response.body}"
203
+ end
204
+ end
205
+
206
+ end
207
+
File without changes
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: slimtimer4r
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Dylan Markow
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-01-09 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: hoe
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.4.0
23
+ version:
24
+ description: The author was too lazy to write a description
25
+ email: dylan@dylanmarkow.com
26
+ executables:
27
+ - slimtimer4r
28
+ extensions: []
29
+
30
+ extra_rdoc_files:
31
+ - History.txt
32
+ - Manifest.txt
33
+ - README.txt
34
+ files:
35
+ - History.txt
36
+ - Manifest.txt
37
+ - README.txt
38
+ - Rakefile
39
+ - bin/slimtimer4r
40
+ - lib/slimtimer4r.rb
41
+ - test/test_slimtimer4r.rb
42
+ has_rdoc: true
43
+ homepage: http://www.zenspider.com/ZSS/Products/slimtimer4r/
44
+ post_install_message:
45
+ rdoc_options:
46
+ - --main
47
+ - README.txt
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: "0"
61
+ version:
62
+ requirements: []
63
+
64
+ rubyforge_project: slimtimer4r
65
+ rubygems_version: 1.0.1
66
+ signing_key:
67
+ specification_version: 2
68
+ summary: The author was too lazy to write a summary
69
+ test_files:
70
+ - test/test_slimtimer4r.rb