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
@@ -0,0 +1,76 @@
1
+ require 'faraday'
2
+ #require 'simple_oauth'
3
+ require 'worksnaps/error'
4
+ require 'worksnaps/api/users'
5
+ require 'worksnaps/api/tasks'
6
+ require 'worksnaps/api/projects'
7
+ require 'worksnaps/api/user_assignments'
8
+ require 'worksnaps/api/task_assignments'
9
+
10
+ module WorkSnaps
11
+ class Client
12
+ include WorkSnaps::API::Users
13
+ include WorkSnaps::API::Tasks
14
+ include WorkSnaps::API::Projects
15
+ include WorkSnaps::API::UserAssignments
16
+ include WorkSnaps::API::TaskAssignments
17
+
18
+ # Initializes a new Client object
19
+ #
20
+ # @param options [Hash]
21
+ # @return [WorkSnaps::Client]
22
+ def initialize(options={})
23
+ Wsnaps.keys.each do |key|
24
+ instance_variable_set(:"@#{key}", options[key] || WorkSnaps.instance_variable_get(:"@#{key}"))
25
+ end
26
+ end
27
+
28
+ # Perform an HTTP DELETE request
29
+ def delete(path, params={})
30
+ request(:delete, path, params)
31
+ end
32
+
33
+ # Perform an HTTP GET request
34
+ def get(path, params={})
35
+ request(:get, path, params)
36
+ end
37
+
38
+ # Perform an HTTP POST request
39
+ def post(path, params={})
40
+ signature_params = params.values.any?{|value| value.respond_to?(:to_io)} ? {} : params
41
+ request(:post, path, params.to_xml, signature_params)
42
+ end
43
+
44
+ # Perform an HTTP PUT request
45
+ def put(path, params={})
46
+ request(:put, path, params)
47
+ end
48
+
49
+ private
50
+
51
+ def request(method, path, params={}, signature_params=params)
52
+ connection.send(method.to_sym, path, params) do |request|
53
+ request.headers[:authorization] = auth_header(method.to_sym, path, signature_params).to_s
54
+ end.env
55
+ rescue Faraday::Error::ClientError
56
+ raise WorkSnaps::Error::ClientError
57
+ end
58
+
59
+ # Returns a Faraday::Connection object
60
+ #
61
+ # @return [Faraday::Connection]
62
+ def connection
63
+ @connection ||= Faraday.new(@endpoint, @connection_options.merge(:builder => @middleware))
64
+ end
65
+
66
+ def auth_header(method, path, params={})
67
+ # Oauth
68
+ # uri = URI(@endpoint + path)
69
+ # SimpleOAuth::Header.new(method, uri, params, WorkSnaps.oauth_credentials)
70
+
71
+ # Basic auth
72
+ Faraday::Request::BasicAuthentication.header(Wsnaps.api_tocken, '')
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,94 @@
1
+ require 'faraday'
2
+ require 'worksnaps/error/client_error'
3
+ require 'worksnaps/error/server_error'
4
+ #require 'faraday/request/multipart'
5
+ #require 'worksnaps/request/multipart_with_file'
6
+ #require 'worksnaps/response/parse_json'
7
+ require 'worksnaps/response/parse_xml'
8
+ require 'worksnaps/response/raise_error'
9
+ require 'worksnaps/version'
10
+
11
+ module WorkSnaps
12
+ module Default
13
+ ENDPOINT = 'http://www.worksnaps.net' unless defined? WorkSnaps::Default::ENDPOINT
14
+ CONNECTION_OPTIONS = {
15
+ :headers => {
16
+ :accept => 'application/xml',
17
+ 'Content-Type' => 'application/xml',
18
+ :user_agent => "WorkSnaps Ruby Gem #{WorkSnaps::Version}",
19
+ },
20
+ :request => {
21
+ :open_timeout => 5,
22
+ :timeout => 10,
23
+ },
24
+ :ssl => {
25
+ :verify => false
26
+ },
27
+ } unless defined? WorkSnaps::Default::CONNECTION_OPTIONS
28
+ IDENTITY_MAP = false unless defined? WorkSnaps::Default::IDENTITY_MAP
29
+ MIDDLEWARE = Faraday::Builder.new do |builder|
30
+ # Convert request params to "www-form-urlencoded"
31
+ builder.use Faraday::Request::UrlEncoded
32
+ # Parse response in XML format to hash
33
+ builder.use WorkSnaps::Response::ParseXML
34
+ # Handle 4xx server responses
35
+ builder.use WorkSnaps::Response::RaiseError, WorkSnaps::Error::ClientError
36
+ # Handle 5xx server responses
37
+ builder.use WorkSnaps::Response::RaiseError, WorkSnaps::Error::ServerError
38
+ # Set Faraday's HTTP adapter
39
+ builder.adapter Faraday.default_adapter
40
+ end unless defined? WorkSnaps::Default::MIDDLEWARE
41
+
42
+ class << self
43
+ def options
44
+ Hash[Wsnaps.keys.map{|key| [key, send(key)]}]
45
+ end
46
+
47
+ # @return [String]
48
+ def api_tocken
49
+ ENV['WORKSNAPS_API_TOCKEN']
50
+ end
51
+
52
+ # @return [String]
53
+ def consumer_key
54
+ ENV['WORKSNAPS_CONSUMER_KEY']
55
+ end
56
+
57
+ # @return [String]
58
+ def consumer_secret
59
+ ENV['WORKSNAPS_CONSUMER_SECRET']
60
+ end
61
+
62
+ # @return [String]
63
+ def oauth_token
64
+ ENV['WORKSNAPS_OAUTH_TOKEN']
65
+ end
66
+
67
+ # @return [String]
68
+ def oauth_token_secret
69
+ ENV['WORKSNAPS_OAUTH_TOKEN_SECRET']
70
+ end
71
+
72
+ def endpoint
73
+ ENDPOINT
74
+ end
75
+
76
+ def connection_options
77
+ CONNECTION_OPTIONS
78
+ end
79
+
80
+ def identity_map
81
+ IDENTITY_MAP
82
+ end
83
+
84
+ # @note Faraday's middleware stack implementation is comparable to that of Rack middleware. The order of middleware is important: the first middleware on the list wraps all others, while the last middleware is the innermost one.
85
+ # @see https://github.com/technoweenie/faraday#advanced-middleware-usage
86
+ # @see http://mislav.uniqpath.com/2011/07/faraday-advanced-http/
87
+ # @return [Faraday::Builder]
88
+ def middleware
89
+ MIDDLEWARE
90
+ end
91
+
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,22 @@
1
+ module WorkSnaps
2
+ class Error < StandardError
3
+ attr_reader :wrapped_exception
4
+
5
+ def self.errors
6
+ @errors ||= Hash[descendants.map{|klass| [klass.const_get(:HTTP_STATUS_CODE), klass]}]
7
+ end
8
+
9
+ def self.descendants
10
+ ObjectSpace.each_object(::Class).select{|klass| klass < self}
11
+ end
12
+
13
+ def initialize(exception=$!, response_headers={})
14
+ @wrapped_exception = exception
15
+ exception.respond_to?(:backtrace) ? super(exception.message) : super(exception.to_s)
16
+ end
17
+
18
+ def backtrace
19
+ @wrapped_exception.respond_to?(:backtrace) ? @wrapped_exception.backtrace : super
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,10 @@
1
+ require 'worksnaps/error/forbidden'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Raised when a Tweet has already been favorited
6
+ class AlreadyFavorited < WorkSnaps::Error
7
+ MESSAGE = "You have already favorited this status"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'worksnaps/error/forbidden'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Raised when a Tweet has already been retweeted
6
+ class AlreadyRetweeted < WorkSnaps::Error
7
+ MESSAGE = "sharing is not permissible for this status (Share validations failed)"
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ require 'worksnaps/error/server_error'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Raised when WorkSnaps returns the HTTP status code 502
6
+ class BadGateway < WorkSnaps::Error::ServerError
7
+ HTTP_STATUS_CODE = 502
8
+ MESSAGE = "WorkSnaps is down or being upgraded."
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ require 'worksnaps/error/client_error'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Raised when WorkSnaps returns the HTTP status code 400
6
+ class BadRequest < WorkSnaps::Error::ClientError
7
+ HTTP_STATUS_CODE = 400
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,35 @@
1
+ require 'worksnaps/error'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Raised when WorkSnaps returns a 4xx HTTP status code or there's an error in Faraday
6
+ class ClientError < WorkSnaps::Error
7
+
8
+ # Create a new error from an HTTP environment
9
+ #
10
+ # @param response [Hash]
11
+ # @return [WorkSnaps::Error]
12
+ def self.from_response(response={})
13
+ new(parse_error(response[:body]), response[:response_headers])
14
+ end
15
+
16
+ private
17
+
18
+ def self.parse_error(body)
19
+ if body.nil?
20
+ ''
21
+ elsif body[:error]
22
+ body[:error]
23
+ elsif body[:errors]
24
+ first = Array(body[:errors]).first
25
+ if first.is_a?(Hash)
26
+ first[:message].chomp
27
+ else
28
+ first.chomp
29
+ end
30
+ end
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,8 @@
1
+ require 'worksnaps/error'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ class ConfigurationError < ::ArgumentError
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ require 'worksnaps/error'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Raised when JSON parsing fails
6
+ class DecodeError < WorkSnaps::Error
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ require 'worksnaps/error/client_error'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Raised when WorkSnaps returns the HTTP status code 403
6
+ class Forbidden < WorkSnaps::Error::ClientError
7
+ HTTP_STATUS_CODE = 403
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ require 'worksnaps/error/server_error'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Raised when WorkSnaps returns the HTTP status code 504
6
+ class GatewayTimeout < WorkSnaps::Error::ServerError
7
+ HTTP_STATUS_CODE = 504
8
+ MESSAGE = "The WorkSnaps servers are up, but the request couldn't be serviced due to some failure within our stack. Try again later."
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ require 'worksnaps/error'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Inherit from KeyError when Ruby 1.8 compatibility is removed
6
+ class IdentityMapKeyError < ::IndexError
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ require 'worksnaps/error/server_error'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Raised when WorkSnaps returns the HTTP status code 500
6
+ class InternalServerError < WorkSnaps::Error::ServerError
7
+ HTTP_STATUS_CODE = 500
8
+ MESSAGE = "Something is technically wrong."
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,10 @@
1
+ require 'worksnaps/error/client_error'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Raised when WorkSnaps returns the HTTP status code 406
6
+ class NotAcceptable < WorkSnaps::Error::ClientError
7
+ HTTP_STATUS_CODE = 406
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ require 'worksnaps/error/client_error'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Raised when WorkSnaps returns the HTTP status code 404
6
+ class NotFound < WorkSnaps::Error::ClientError
7
+ HTTP_STATUS_CODE = 404
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,28 @@
1
+ require 'worksnaps/error'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Raised when WorkSnaps returns a 5xx HTTP status code
6
+ class ServerError < WorkSnaps::Error
7
+ MESSAGE = "Server Error"
8
+
9
+ # Create a new error from an HTTP environment
10
+ #
11
+ # @param response [Hash]
12
+ # @return [WorkSnaps::Error]
13
+ def self.from_response(response={})
14
+ new(nil, response[:response_headers])
15
+ end
16
+
17
+ # Initializes a new ServerError object
18
+ #
19
+ # @param message [String]
20
+ # @param response_headers [Hash]
21
+ # @return [WorkSnaps::Error::ServerError]
22
+ def initialize(message=nil, response_headers={})
23
+ super((message || self.class.const_get(:MESSAGE)), response_headers)
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ require 'worksnaps/error/server_error'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Raised when WorkSnaps returns the HTTP status code 503
6
+ class ServiceUnavailable < WorkSnaps::Error::ServerError
7
+ HTTP_STATUS_CODE = 503
8
+ MESSAGE = "(__-){ WorkSnaps is over capacity."
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,12 @@
1
+ require 'worksnaps/error/client_error'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Raised when WorkSnaps returns the HTTP status code 429
6
+ class TooManyRequests < WorkSnaps::Error::ClientError
7
+ HTTP_STATUS_CODE = 429
8
+ end
9
+ EnhanceYourCalm = TooManyRequests
10
+ RateLimited = TooManyRequests
11
+ end
12
+ end
@@ -0,0 +1,8 @@
1
+ module WorkSnaps
2
+ class Error
3
+ class Unauthorized < WorkSnaps::Error
4
+ HTTP_STATUS_CODE = 401
5
+ end
6
+ end
7
+ end
8
+
@@ -0,0 +1,10 @@
1
+ require 'worksnaps/error/client_error'
2
+
3
+ module WorkSnaps
4
+ class Error
5
+ # Raised when WorkSnaps returns the HTTP status code 404
6
+ class UnprocessableEntity < WorkSnaps::Error::ClientError
7
+ HTTP_STATUS_CODE = 422
8
+ end
9
+ end
10
+ end