wsnaps 1.0 → 1.0.1

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.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/lib/worksnaps/api/arguments.rb +13 -0
  3. data/lib/worksnaps/api/projects.rb +26 -0
  4. data/lib/worksnaps/api/task_assignments.rb +26 -0
  5. data/lib/worksnaps/api/tasks.rb +30 -0
  6. data/lib/worksnaps/api/time_entries.rb +30 -0
  7. data/lib/worksnaps/api/user_assignments.rb +30 -0
  8. data/lib/worksnaps/api/users.rb +26 -0
  9. data/lib/worksnaps/api/utils.rb +182 -0
  10. data/lib/worksnaps/base.rb +117 -0
  11. data/lib/worksnaps/client.rb +76 -0
  12. data/lib/worksnaps/default.rb +94 -0
  13. data/lib/worksnaps/error.rb +22 -0
  14. data/lib/worksnaps/error/already_favorited.rb +10 -0
  15. data/lib/worksnaps/error/already_retweeted.rb +10 -0
  16. data/lib/worksnaps/error/bad_gateway.rb +11 -0
  17. data/lib/worksnaps/error/bad_request.rb +10 -0
  18. data/lib/worksnaps/error/client_error.rb +35 -0
  19. data/lib/worksnaps/error/configuration_error.rb +8 -0
  20. data/lib/worksnaps/error/decode_error.rb +9 -0
  21. data/lib/worksnaps/error/forbidden.rb +10 -0
  22. data/lib/worksnaps/error/gateway_timeout.rb +11 -0
  23. data/lib/worksnaps/error/identity_map_key_error.rb +9 -0
  24. data/lib/worksnaps/error/internal_server_error.rb +11 -0
  25. data/lib/worksnaps/error/not_acceptable.rb +10 -0
  26. data/lib/worksnaps/error/not_found.rb +10 -0
  27. data/lib/worksnaps/error/server_error.rb +28 -0
  28. data/lib/worksnaps/error/service_unavailable.rb +11 -0
  29. data/lib/worksnaps/error/too_many_requests.rb +12 -0
  30. data/lib/worksnaps/error/unauthorized.rb +8 -0
  31. data/lib/worksnaps/error/unprocessable_entity.rb +10 -0
  32. data/lib/worksnaps/helper.rb +37 -0
  33. data/lib/worksnaps/project.rb +7 -0
  34. data/lib/worksnaps/request/multipart_with_file.rb +34 -0
  35. data/lib/worksnaps/response/parse_json.rb +25 -0
  36. data/lib/worksnaps/response/parse_xml.rb +25 -0
  37. data/lib/worksnaps/response/raise_error.rb +33 -0
  38. data/lib/worksnaps/task.rb +7 -0
  39. data/lib/worksnaps/task_assignment.rb +7 -0
  40. data/lib/worksnaps/user.rb +13 -0
  41. data/lib/worksnaps/user_assignment.rb +7 -0
  42. data/lib/worksnaps/version.rb +14 -0
  43. data/lib/wsnaps.rb +68 -3
  44. metadata +44 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: efdfcc67158b76a509df614675403e006b5311dc
4
- data.tar.gz: 573c00d36967ced954e643f7515861d515a9689a
3
+ metadata.gz: 95e3846dd8eceef1d11ef189a30b3139360251e9
4
+ data.tar.gz: 6fad1b153a47fdffef2a39588f9ede3c82e25042
5
5
  SHA512:
6
- metadata.gz: 3408d81663caa9728efc2c358bac8f7d5b4a6155d3467ee8d14b585b85d30620035d4544198622000768856bbe6f886b7a809a2c985740914b598af956fa6127
7
- data.tar.gz: be3ef2b9a1b157328872740627042cea1f70014fb621221c0cbce2944500d4223d79c2881592db57ffedcbc334d956d48a33458b66965770efc0386907bd1eb6
6
+ metadata.gz: 1f112476a6987fed7d5cab27db1265f6c29afde4c60b7507839c7063a008ed14b2f22202a13e1087437724795095b865c1c509e5a9812e4a1b4cb3b78ccb290d
7
+ data.tar.gz: 336726c216e84f849c9e04ace43f253751483b854a0d4e30576ced07a329148d46d045ddeb20342022ef0f5af9c850898378b472c970bcbdd140850dc75904ac
@@ -0,0 +1,13 @@
1
+ module WorkSnaps
2
+ module API
3
+ class Arguments < Array
4
+ attr_reader :options
5
+
6
+ def initialize(args)
7
+ @options = args.last.is_a?(::Hash) ? args.pop : {}
8
+ super(args)
9
+ end
10
+
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ require 'worksnaps/project'
2
+ require 'worksnaps/api/utils'
3
+
4
+ module WorkSnaps
5
+ module API
6
+ module Projects
7
+ include WorkSnaps::API::Utils
8
+
9
+ def create_project(project_info)
10
+ object_from_response(WorkSnaps::Project, :post, '/api/projects.xml', {:project => project_info})
11
+ end
12
+
13
+ def update_project(p_id, project_info)
14
+ object_from_response(WorkSnaps::Project, :put, "/api/projects/#{p_id}.xml", {:project => project_info})
15
+ end
16
+
17
+ def project(p_id)
18
+ object_from_response(WorkSnaps::Project, :get, "/api/projects/#{p_id}.xml")
19
+ end
20
+
21
+ def projects
22
+ objects_from_response(WorkSnaps::Project, :get, '/api/projects.xml')
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,26 @@
1
+ require 'worksnaps/task_assignment'
2
+ require 'worksnaps/api/utils'
3
+
4
+ module WorkSnaps
5
+ module API
6
+ module TaskAssignments
7
+ include WorkSnaps::API::Utils
8
+
9
+ def create_task_assignment(p_id, assignment_info)
10
+ object_from_response(WorkSnaps::TaskAssignment, :post, "/api/projects/#{p_id}/task_assignments.xml", {:task_assignment => assignment_info})
11
+ end
12
+
13
+ def delete_task_assignment(p_id, assignment_id)
14
+ object_from_response(WorkSnaps::TaskAssignment, :delete, "/api/projects/#{p_id}/task_assignments/#{assignment_id}.xml")
15
+ end
16
+
17
+ def task_assignment(p_id, assignment_id)
18
+ object_from_response(WorkSnaps::TaskAssignment, :get, "/api/projects/#{p_id}/task_assignments/#{assignment_id}.xml")
19
+ end
20
+
21
+ def task_assignments(p_id)
22
+ objects_from_response(WorkSnaps::TaskAssignment, :get, "/api/projects/#{p_id}/task_assignments.xml")
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,30 @@
1
+ require 'worksnaps/task'
2
+ require 'worksnaps/api/utils'
3
+
4
+ module WorkSnaps
5
+ module API
6
+ module Tasks
7
+ include WorkSnaps::API::Utils
8
+
9
+ def create_task(p_id, task_info)
10
+ object_from_response(WorkSnaps::Task, :post, "/api/projects/#{p_id}/tasks.xml", {:task => task_info})
11
+ end
12
+
13
+ def update_task(p_id, t_id, task_info)
14
+ object_from_response(WorkSnaps::Task, :put, "/api/projects/#{p_id}/tasks/#{t_id}.xml", {:task => task_info})
15
+ end
16
+
17
+ def delete_task(p_id, t_id)
18
+ object_from_response(WorkSnaps::Task, :delete, "/api/projects/#{p_id}/tasks/#{t_id}.xml")
19
+ end
20
+
21
+ def task(p_id, t_id)
22
+ object_from_response(WorkSnaps::Task, :get, "/api/projects/#{p_id}/tasks/#{t_id}.xml")
23
+ end
24
+
25
+ def tasks(p_id)
26
+ objects_from_response(WorkSnaps::Task, :get, "/api/projects/#{p_id}/tasks.xml")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ require 'worksnaps/time_entry'
2
+ require 'worksnaps/api/utils'
3
+
4
+ module WorkSnaps
5
+ module API
6
+ module TimeEntries
7
+ include WorkSnaps::API::Utils
8
+
9
+ def create_task_assignment(p_id, assignment_info)
10
+ object_from_response(WorkSnaps::TaskAssignment, :post, "/api/projects/#{p_id}/task_assignments.xml", {:task_assignment => assignment_info})
11
+ end
12
+
13
+ def delete_task_assignment(p_id, assignment_id)
14
+ object_from_response(WorkSnaps::TaskAssignment, :delete, "/api/projects/#{p_id}/task_assignments/#{assignment_id}.xml")
15
+ end
16
+
17
+ def time_entry(p_id, entry_id)
18
+ object_from_response(WorkSnaps::TaskAssignment, :get, "/api/projects/#{p_id}/time_entries/#{entry_id}.xml")
19
+ end
20
+
21
+ def screen_short(p_id, entry_id)
22
+ object_from_response(WorkSnaps::TaskAssignment, :get, "/api/projects/#{p_id}/time_entries/#{entry_id}.xml?full_resolution_url=1")
23
+ end
24
+
25
+ def task_assignments(p_id)
26
+ objects_from_response(WorkSnaps::TaskAssignment, :get, "/api/projects/#{p_id}/task_assignments.xml")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,30 @@
1
+ require 'worksnaps/user_assignment'
2
+ require 'worksnaps/api/utils'
3
+
4
+ module WorkSnaps
5
+ module API
6
+ module UserAssignments
7
+ include WorkSnaps::API::Utils
8
+
9
+ def create_user_assignment(p_id, assignment_info)
10
+ object_from_response(WorkSnaps::UserAssignment, :post, "/api/projects/#{p_id}/user_assignments.xml", {:user_assignment => assignment_info})
11
+ end
12
+
13
+ def update_user_assignment(p_id, assignment_id, assignment_info)
14
+ object_from_response(WorkSnaps::UserAssignment, :put, "/api/projects/#{p_id}/user_assignments/#{assignment_id}.xml", {:user_assignment => project_info})
15
+ end
16
+
17
+ def delete_user_assignment(p_id, assignment_id)
18
+ object_from_response(WorkSnaps::UserAssignment, :delete, "/api/projects/#{p_id}/user_assignments/#{assignment_id}.xml")
19
+ end
20
+
21
+ def user_assignment(p_id, assignment_id)
22
+ object_from_response(WorkSnaps::UserAssignment, :get, "/api/projects/#{p_id}/user_assignments/#{assignment_id}.xml")
23
+ end
24
+
25
+ def user_assignments(p_id)
26
+ objects_from_response(WorkSnaps::UserAssignment, :get, "/api/projects/#{p_id}/user_assignments.xml")
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ require 'worksnaps/user'
2
+ require 'worksnaps/api/utils'
3
+
4
+ module WorkSnaps
5
+ module API
6
+ module Users
7
+ include WorkSnaps::API::Utils
8
+
9
+ def create_user(user_info)
10
+ object_from_response(WorkSnaps::User, :post, '/api/users.xml', {:user => user_info})
11
+ end
12
+
13
+ def update_user(user_id, user_info)
14
+ object_from_response(WorkSnaps::User, :put, "/api/users/#{user_id}.xml", {:user => user_info})
15
+ end
16
+
17
+ def user(user_id)
18
+ object_from_response(WorkSnaps::User, :get, "/api/users/#{user_id}.xml")
19
+ end
20
+
21
+ def current_user
22
+ object_from_response(WorkSnaps::User, :get, '/api/me.xml')
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,182 @@
1
+ require 'worksnaps/api/arguments'
2
+
3
+ module WorkSnaps
4
+ module API
5
+ module Utils
6
+
7
+ DEFAULT_CURSOR = -1
8
+
9
+ private
10
+ # @param klass [Class]
11
+ # @param request_method [Symbol]
12
+ # @param path [String]
13
+ # @param options [Hash]
14
+ # @return [Object]
15
+ def object_from_response(klass, request_method, path, options={})
16
+ response = send(request_method.to_sym, path, options)[:body]
17
+ klass.fetch_or_new(object_flatten(klass, response))
18
+ end
19
+
20
+ def objects_from_response(klass, request_method, path, options={})
21
+ response = send(request_method.to_sym, path, options)[:body]
22
+ objects_array_from_response(klass, response).map {|object_hash|
23
+ klass.fetch_or_new(object_flatten(klass, object_hash))
24
+ }
25
+ end
26
+
27
+ def objects_array_from_response(klass, response)
28
+ objects_hash = response[klass.name.demodulize.tableize]
29
+ objects_hash ? objects_hash.values : []
30
+ end
31
+
32
+ def object_flatten(klass, attrs = {})
33
+ attrs ||= {}
34
+ object = attrs[klass.name.demodulize.underscore] || {}
35
+ object.symbolize_keys!
36
+ end
37
+ =begin
38
+ # @param request_method [Symbol]
39
+ # @param path [String]
40
+ # @param args [Array]
41
+ # @return [Array<WorkSnaps::User>]
42
+ def threaded_user_objects_from_response(request_method, path, args)
43
+ arguments = WorkSnaps::API::Arguments.new(args)
44
+ arguments.flatten.threaded_map do |user|
45
+ object_from_response(WorkSnaps::User, request_method, path, merge_user(arguments.options, user))
46
+ end
47
+ end
48
+
49
+ # @param request_method [Symbol]
50
+ # @param path [String]
51
+ # @param args [Array]
52
+ # @return [Array<WorkSnaps::User>]
53
+ def user_objects_from_response(request_method, path, args)
54
+ arguments = WorkSnaps::API::Arguments.new(args)
55
+ merge_user!(arguments.options, arguments.pop || screen_name) unless arguments.options[:user_id] || arguments.options[:screen_name]
56
+ objects_from_response(WorkSnaps::User, request_method, path, arguments.options)
57
+ end
58
+
59
+ # @param klass [Class]
60
+ # @param request_method [Symbol]
61
+ # @param path [String]
62
+ # @param args [Array]
63
+ # @return [Array]
64
+ def objects_from_response_with_user(klass, request_method, path, args)
65
+ arguments = WorkSnaps::API::Arguments.new(args)
66
+ merge_user!(arguments.options, arguments.pop)
67
+ objects_from_response(klass, request_method, path, arguments.options)
68
+ end
69
+
70
+ # @param klass [Class]
71
+ # @param request_method [Symbol]
72
+ # @param path [String]
73
+ # @param options [Hash]
74
+ # @return [Array]
75
+ def objects_from_response(klass, request_method, path, options={})
76
+ response = send(request_method.to_sym, path, options)[:body]
77
+ objects_from_array(klass, response)
78
+ end
79
+
80
+ # @param klass [Class]
81
+ # @param array [Array]
82
+ # @return [Array]
83
+ def objects_from_array(klass, array)
84
+ array.map do |element|
85
+ klass.fetch_or_new(element)
86
+ end
87
+ end
88
+
89
+ # @param klass [Class]
90
+ # @param request_method [Symbol]
91
+ # @param path [String]
92
+ # @param args [Array]
93
+ # @return [Array]
94
+ def threaded_object_from_response(klass, request_method, path, args)
95
+ arguments = WorkSnaps::API::Arguments.new(args)
96
+ arguments.flatten.threaded_map do |id|
97
+ object_from_response(klass, request_method, path, arguments.options.merge(:id => id))
98
+ end
99
+ end
100
+
101
+ # @param klass [Class]
102
+ # @param request_method [Symbol]
103
+ # @param path [String]
104
+ # @param options [Hash]
105
+ # @return [Object]
106
+ def object_from_response(klass, request_method, path, options={})
107
+ response = send(request_method.to_sym, path, options)
108
+ klass.from_response(response)
109
+ end
110
+
111
+ def handle_forbidden_error(klass, error)
112
+ if error.message == klass::MESSAGE
113
+ raise klass.new
114
+ else
115
+ raise error
116
+ end
117
+ end
118
+
119
+ def screen_name
120
+ @screen_name ||= verify_credentials.screen_name
121
+ end
122
+
123
+ # Take a user and merge it into the hash with the correct key
124
+ #
125
+ # @param hash [Hash]
126
+ # @param user [Integer, String, WorkSnaps::User] A WorkSnaps user ID, screen_name, or object.
127
+ # @return [Hash]
128
+ def merge_user(hash, user, prefix=nil)
129
+ merge_user!(hash.dup, user, prefix)
130
+ end
131
+
132
+ # Take a user and merge it into the hash with the correct key
133
+ #
134
+ # @param hash [Hash]
135
+ # @param user [Integer, String, WorkSnaps::User] A WorkSnaps user ID, screen_name, or object.
136
+ # @return [Hash]
137
+ def merge_user!(hash, user, prefix=nil)
138
+ case user
139
+ when Integer
140
+ hash[[prefix, "user_id"].compact.join("_").to_sym] = user
141
+ when String
142
+ hash[[prefix, "screen_name"].compact.join("_").to_sym] = user
143
+ when WorkSnaps::User
144
+ hash[[prefix, "user_id"].compact.join("_").to_sym] = user.id
145
+ end
146
+ hash
147
+ end
148
+
149
+ # Take a multiple users and merge them into the hash with the correct keys
150
+ #
151
+ # @param hash [Hash]
152
+ # @param users [Array<Integer, String, WorkSnaps::User>, Set<Integer, String, WorkSnaps::User>] An array of WorkSnaps user IDs, screen_names, or objects.
153
+ # @return [Hash]
154
+ def merge_users(hash, users)
155
+ merge_users!(hash.dup, users)
156
+ end
157
+
158
+ # Take a multiple users and merge them into the hash with the correct keys
159
+ #
160
+ # @param hash [Hash]
161
+ # @param users [Array<Integer, String, WorkSnaps::User>, Set<Integer, String, WorkSnaps::User>] An array of WorkSnaps user IDs, screen_names, or objects.
162
+ # @return [Hash]
163
+ def merge_users!(hash, users)
164
+ user_ids, screen_names = [], []
165
+ users.flatten.each do |user|
166
+ case user
167
+ when Integer
168
+ user_ids << user
169
+ when String
170
+ screen_names << user
171
+ when WorkSnaps::User
172
+ user_ids << user.id
173
+ end
174
+ end
175
+ hash[:user_id] = user_ids.join(',') unless user_ids.empty?
176
+ hash[:screen_name] = screen_names.join(',') unless screen_names.empty?
177
+ hash
178
+ end
179
+ =end
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,117 @@
1
+ require 'worksnaps/error/identity_map_key_error'
2
+
3
+ module WorkSnaps
4
+ class Base
5
+ # Define methods that retrieve the value from an initialized instance variable Hash, using the attribute as a key
6
+ #
7
+ # @param attrs [Array, Set, Symbol]
8
+ def self.attr_reader(*attrs)
9
+ mod = Module.new do
10
+ attrs.each do |attribute|
11
+ define_method attribute do
12
+ @attrs[attribute.to_sym]
13
+ end
14
+ define_method "#{attribute}?" do
15
+ !!@attrs[attribute.to_sym]
16
+ end
17
+ end
18
+ end
19
+ const_set(:Attributes, mod)
20
+ include mod
21
+ end
22
+
23
+ # return [WorkSnaps::IdentityMap]
24
+ def self.identity_map
25
+ return unless WorkSnaps.identity_map
26
+ @identity_map = WorkSnaps.identity_map.new unless defined?(@identity_map) && @identity_map.class == WorkSnaps.identity_map
27
+ @identity_map
28
+ end
29
+
30
+ # Retrieves an object from the identity map.
31
+ #
32
+ # @param attrs [Hash]
33
+ # @return [WorkSnaps::Base]
34
+ def self.fetch(attrs)
35
+ return unless identity_map
36
+ if object = identity_map.fetch(Marshal.dump(attrs))
37
+ return object
38
+ end
39
+ return yield if block_given?
40
+ raise WorkSnaps::Error::IdentityMapKeyError, "key not found"
41
+ end
42
+
43
+ # Stores an object in the identity map.
44
+ #
45
+ # @param object [Object]
46
+ # @return [WorkSnaps::Base]
47
+ def self.store(object)
48
+ return object unless identity_map
49
+ identity_map.store(Marshal.dump(object.attrs), object)
50
+ end
51
+
52
+ # Retrieves an object from the identity map, or stores it in the
53
+ # identity map if it doesn't already exist.
54
+ #
55
+ # @param attrs [Hash]
56
+ # @return [WorkSnaps::Base]
57
+ def self.fetch_or_new(attrs={})
58
+ return unless attrs
59
+ return new(attrs) unless identity_map
60
+
61
+ fetch(attrs) do
62
+ object = new(attrs)
63
+ store(object)
64
+ end
65
+ end
66
+
67
+ # Initializes a new object
68
+ #
69
+ # @param attrs [Hash]
70
+ # @return [WorkSnaps::Base]
71
+ def initialize(attrs={})
72
+ @attrs = attrs
73
+ end
74
+
75
+ # Fetches an attribute of an object using hash notation
76
+ #
77
+ # @param method [String, Symbol] Message to send to the object
78
+ def [](method)
79
+ send(method.to_sym)
80
+ rescue NoMethodError
81
+ nil
82
+ end
83
+
84
+ # Retrieve the attributes of an object
85
+ #
86
+ # @return [Hash]
87
+ def attrs
88
+ @attrs
89
+ end
90
+ alias to_hash attrs
91
+
92
+ # Update the attributes of an object
93
+ #
94
+ # @param attrs [Hash]
95
+ # @return [WorkSnaps::Base]
96
+ def update(attrs)
97
+ @attrs.update(attrs)
98
+ self
99
+ end
100
+
101
+ protected
102
+
103
+ # @param attr [Symbol]
104
+ # @param other [WorkSnaps::Base]
105
+ # @return [Boolean]
106
+ def attr_equal(attr, other)
107
+ self.class == other.class && !other.send(attr).nil? && send(attr) == other.send(attr)
108
+ end
109
+
110
+ # @param other [WorkSnaps::Base]
111
+ # @return [Boolean]
112
+ def attrs_equal(other)
113
+ self.class == other.class && !other.attrs.empty? && attrs == other.attrs
114
+ end
115
+
116
+ end
117
+ end