amiando 0.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 (104) hide show
  1. data/.gitignore +6 -0
  2. data/Gemfile +17 -0
  3. data/Guardfile +11 -0
  4. data/README.md +26 -0
  5. data/Rakefile +12 -0
  6. data/amiando.gemspec +27 -0
  7. data/lib/amiando.rb +59 -0
  8. data/lib/amiando/api_key.rb +35 -0
  9. data/lib/amiando/boolean.rb +33 -0
  10. data/lib/amiando/event.rb +131 -0
  11. data/lib/amiando/request.rb +38 -0
  12. data/lib/amiando/resource.rb +152 -0
  13. data/lib/amiando/result.rb +33 -0
  14. data/lib/amiando/ticket_category.rb +99 -0
  15. data/lib/amiando/ticket_shop.rb +63 -0
  16. data/lib/amiando/user.rb +148 -0
  17. data/lib/amiando/version.rb +3 -0
  18. data/test/amiando/amiando_test.rb +13 -0
  19. data/test/amiando/api_key_test.rb +58 -0
  20. data/test/amiando/boolean_test.rb +21 -0
  21. data/test/amiando/event_test.rb +141 -0
  22. data/test/amiando/resource_test.rb +68 -0
  23. data/test/amiando/result_test.rb +25 -0
  24. data/test/amiando/ticket_category_test.rb +89 -0
  25. data/test/amiando/ticket_shop_test.rb +42 -0
  26. data/test/amiando/user_test.rb +130 -0
  27. data/test/fixtures/ApiKey/018fa0a2281ec9026bc122bc346366f6.yml +60 -0
  28. data/test/fixtures/ApiKey/1f62195e173114773b3ec2613582ece9.yml +60 -0
  29. data/test/fixtures/ApiKey/76860dbafe66279f25f56cd66b3f6ba1.yml +62 -0
  30. data/test/fixtures/ApiKey/97d82801a10696aaf385bf5873034b60.yml +60 -0
  31. data/test/fixtures/ApiKey/a703d1fcec1576fa8cb4ca1c5f53f545.yml +62 -0
  32. data/test/fixtures/ApiKey/a948a98b153ab66978e37160f352bfbc.yml +60 -0
  33. data/test/fixtures/ApiKey/b7ecc9e79dd856dec661554cd00490ed.yml +62 -0
  34. data/test/fixtures/ApiKey/ded8694c21d2e1c0cec845f72ba452b5.yml +60 -0
  35. data/test/fixtures/ApiKey/fa883db60c0390aa8948098d32497015.yml +60 -0
  36. data/test/fixtures/Event/29a95cd545b2fba8121dce97a3c859e3.yml +60 -0
  37. data/test/fixtures/Event/361940ebc5f074b1d6d96c2dbeb573ab.yml +60 -0
  38. data/test/fixtures/Event/3a90bf0a17eb1d647f1496d04640797a.yml +60 -0
  39. data/test/fixtures/Event/3b8ae154ad13c7152366b79c0d34b053.yml +60 -0
  40. data/test/fixtures/Event/49877df5f8c251e3364a3560ab1ab46c.yml +60 -0
  41. data/test/fixtures/Event/50cb3d76b40032b0fa5731ce7d2ae2f6.yml +62 -0
  42. data/test/fixtures/Event/5d6016557d86e7b7ff83d07d1ef4bf44.yml +60 -0
  43. data/test/fixtures/Event/67e55d2f91fa702eb8dc612cbfa661f9.yml +60 -0
  44. data/test/fixtures/Event/813535fc6ee153c1a6d8e826f1fe04dc.yml +60 -0
  45. data/test/fixtures/Event/8eabb0f839e03cde5818397c7121e6b4.yml +61 -0
  46. data/test/fixtures/Event/96a5ccd0281a67a4bdb276516b77e756.yml +62 -0
  47. data/test/fixtures/Event/9e689bd5495dc898a710cba8e6d1d779.yml +62 -0
  48. data/test/fixtures/Event/a816e5664ff66b8e3d27b74435a0c123.yml +60 -0
  49. data/test/fixtures/Event/c5ad7e1d1c160d7d1132297892a9ec94.yml +60 -0
  50. data/test/fixtures/Event/c88c85889575508f75deee325e16e49d.yml +60 -0
  51. data/test/fixtures/Event/d6a585196f1a2a94d22f22a2140d4c07.yml +60 -0
  52. data/test/fixtures/Event/e00eebd4faf194fe592fa6e7615909b8.yml +60 -0
  53. data/test/fixtures/Event/e753b6f404795c6635856ea43b0c7d35.yml +60 -0
  54. data/test/fixtures/Event/eb341dbccefaad75aad439f10cc7d82d.yml +60 -0
  55. data/test/fixtures/Event/ebab641e40ca57f8e0883d8ea003bd78.yml +60 -0
  56. data/test/fixtures/Event/ef17351e4bbc84eb776fe16dda31e1e4.yml +62 -0
  57. data/test/fixtures/Global/505952258352958b3b59a3812372ed02.yml +60 -0
  58. data/test/fixtures/Global/d41a6ca323b5db99b4e3c06e108c52cc.yml +60 -0
  59. data/test/fixtures/TicketCategory/0412c9d453efd804e171c6ba57fd980a.yml +66 -0
  60. data/test/fixtures/TicketCategory/49877df5f8c251e3364a3560ab1ab46c.yml +60 -0
  61. data/test/fixtures/TicketCategory/4d3f8d9ff3fb728fc37aaa6e40355a00.yml +62 -0
  62. data/test/fixtures/TicketCategory/5d4fdfda01ed8193c6bbc5e089db5a4b.yml +60 -0
  63. data/test/fixtures/TicketCategory/655e7a8089d67b8eeea1176398e4b289.yml +60 -0
  64. data/test/fixtures/TicketCategory/a9b19dc83437d00ffc4603c04f78159f.yml +62 -0
  65. data/test/fixtures/TicketCategory/bee3d6eb4247fec0849d91fb2f768524.yml +60 -0
  66. data/test/fixtures/TicketCategory/c6f8563714904f006b28ac06312b107d.yml +60 -0
  67. data/test/fixtures/TicketCategory/e6076c26b1b75eec091c5b91c9f75ad9.yml +62 -0
  68. data/test/fixtures/TicketCategory/ebfcf07be91b8cb6d05156713592abc9.yml +60 -0
  69. data/test/fixtures/TicketCategory/fe63648cf867613ec93b380e06257349.yml +60 -0
  70. data/test/fixtures/TicketShop/03d35073550910e61201cf425b4ff73e.yml +60 -0
  71. data/test/fixtures/TicketShop/0524d80dc6e3fad88d49adf71ffa2ab9.yml +60 -0
  72. data/test/fixtures/TicketShop/09729fb0d9f1490bec3acfa0e6742190.yml +60 -0
  73. data/test/fixtures/TicketShop/15c36c73e9f1d3255a61a559e3b98562.yml +60 -0
  74. data/test/fixtures/TicketShop/4605dd240202cd7510bfecaf474ac615.yml +62 -0
  75. data/test/fixtures/TicketShop/5c1f5488a196f44f2c18cc186816fd42.yml +60 -0
  76. data/test/fixtures/TicketShop/71f80402a72be32fdd34074d4426b765.yml +62 -0
  77. data/test/fixtures/TicketShop/bc24338e918c6edb07a55f4d580c5af3.yml +60 -0
  78. data/test/fixtures/TicketShop/d095062bf22d235f277c979b025e5cac.yml +60 -0
  79. data/test/fixtures/TicketShop/ece5150c24e5000bf4eff8dcdb6311bb.yml +60 -0
  80. data/test/fixtures/User/0b4a60c6c962b4b3af9ab21832cd76b2.yml +60 -0
  81. data/test/fixtures/User/0f635f4bb82fdc84af205efe76f43ae0.yml +60 -0
  82. data/test/fixtures/User/1c2f2c8a5372e998f38b9d387107cee2.yml +60 -0
  83. data/test/fixtures/User/1e3ab0fb92b5b1992f35256b4be7497b.yml +71 -0
  84. data/test/fixtures/User/3bac6d29256056f2b9a1ea6fad26966d.yml +60 -0
  85. data/test/fixtures/User/3ffaba64188557400a8678dbefd75990.yml +60 -0
  86. data/test/fixtures/User/5a26c7f9edf6d6027b19b57feda4a96f.yml +60 -0
  87. data/test/fixtures/User/5c17b4b5287f5d0ba390e25e99cf2270.yml +49 -0
  88. data/test/fixtures/User/6501a4db53a97afe6f7b9afeeb996888.yml +60 -0
  89. data/test/fixtures/User/6ad0dd77081f413e3df25d6a625d38cd.yml +60 -0
  90. data/test/fixtures/User/7d493f7758d9795ad522bc827cb51b77.yml +60 -0
  91. data/test/fixtures/User/89e6cb6ae39e29a154c99e0e33bb1b91.yml +60 -0
  92. data/test/fixtures/User/90a3bfe214f17305e356ad3f1a9c9ce7.yml +60 -0
  93. data/test/fixtures/User/92ad6537c8be5aab7cbd778d424f4944.yml +60 -0
  94. data/test/fixtures/User/9485b68940997e23e3721a413d4fbdd5.yml +49 -0
  95. data/test/fixtures/User/98348fe6fbecb7916faadd835916d94d.yml +60 -0
  96. data/test/fixtures/User/b63d7aa4703a3140b4d9884e9f302362.yml +60 -0
  97. data/test/fixtures/User/b8c3fd04d7bd0925c3ccd3a3978ab8e6.yml +49 -0
  98. data/test/fixtures/User/baa28f50439b903e423dbdf918fff20b.yml +62 -0
  99. data/test/fixtures/User/e51278f9f771be0c6c3ac0e4ee1b6459.yml +59 -0
  100. data/test/fixtures/User/eb30a195ac7829d506954f472e9e6dea.yml +60 -0
  101. data/test/support/factory.rb +45 -0
  102. data/test/support/hydra_cache.rb +59 -0
  103. data/test/test_helper.rb +36 -0
  104. metadata +330 -0
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ /.rvmrc
6
+ /TAGS
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in amiando.gemspec
4
+ gemspec
5
+
6
+ unless ENV["TRAVIS"]
7
+ gem 'ruby-debug19', :platforms => :ruby_19
8
+ gem 'ruby-debug', :platforms => :mri_18
9
+ end
10
+
11
+ group :development do
12
+ gem 'guard-minitest'
13
+ if RbConfig::CONFIG['target_os'] =~ /darwin/i
14
+ gem 'rb-fsevent', '>= 0.4.0', :require => false
15
+ gem 'growl', '~> 1.0.3', :require => false
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'minitest' do
5
+ # with Minitest::Unit
6
+ watch(%r|^test/(.*)_test\.rb|)
7
+ watch(%r|^lib/(.*)([^/]+)\.rb|) { |m| "test/#{m[1]}#{m[2]}_test.rb" }
8
+ watch(%r|^test/test_helper\.rb|) { "test" }
9
+ watch(%r|^test/support/(.*)\.rb|) { "test" }
10
+ watch(%r|^lib/amiando.rb|) { "test" }
11
+ end
@@ -0,0 +1,26 @@
1
+ # amiando
2
+
3
+ This is a gem to access the amiando REST API. You can check the original
4
+ documentation here:
5
+
6
+ http://developers.amiando.com/index.php/REST_API
7
+
8
+ ## Basic usage
9
+
10
+ The gem has been implemented with the idea that requests can be done in
11
+ parallel using [Typhoeus](https://github.com/dbalatero/typhoeus).
12
+
13
+ You can query multiple requests and run then like this:
14
+
15
+ ```ruby
16
+ albert = Amiando::User.find(1234)
17
+ jorge = Amiando::User.find(5678)
18
+
19
+ Amiando.run
20
+ ```
21
+
22
+ Both requests will happen in parallel.
23
+
24
+ All attributes should be used in snake_case format instead of the CamelCase
25
+ used in the official documentation. For example, for a user, you should call
26
+ first_name instead of firstName.
@@ -0,0 +1,12 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake'
3
+ require 'rake/testtask'
4
+
5
+ task :default => :test
6
+
7
+ Rake::TestTask.new do |t|
8
+ t.libs << 'test'
9
+ t.pattern = "test/**/*_test.rb"
10
+ t.verbose = true
11
+ end
12
+ Rake::Task['test'].comment = "Run all tests"
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "amiando/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "amiando"
7
+ s.version = Amiando::VERSION
8
+ s.authors = ["Jorge Dias", "Albert Llop"]
9
+ s.email = ["jorge@mrdias.com","mrsimo@gmail.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{A ruby client for the amiando REST API}
12
+ s.description = %q{A ruby client for the amiando REST API with parallel requests in mind}
13
+
14
+ s.rubyforge_project = "amiando"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_dependency 'yajl-ruby', '0.8.2'
22
+ s.add_dependency 'typhoeus', '0.2.4'
23
+
24
+ s.add_development_dependency 'minitest'
25
+ s.add_development_dependency 'webmock'
26
+ s.add_development_dependency 'rake'
27
+ end
@@ -0,0 +1,59 @@
1
+ require "amiando/version"
2
+ require "typhoeus"
3
+ require "yajl"
4
+
5
+ module Amiando
6
+ autoload :Request, 'amiando/request'
7
+ autoload :Resource, 'amiando/resource'
8
+ autoload :Boolean, 'amiando/boolean'
9
+ autoload :Result, 'amiando/result'
10
+ autoload :ApiKey, 'amiando/api_key'
11
+ autoload :User, 'amiando/user'
12
+ autoload :Event, 'amiando/event'
13
+ autoload :TicketCategory, 'amiando/ticket_category'
14
+ autoload :TicketShop, 'amiando/ticket_shop'
15
+
16
+ module Error
17
+ class ServiceDown < Exception; end
18
+ class ApiKeyNeeded < Exception; end
19
+ class NotAuthorized < Exception; end
20
+ class NotFound < Exception; end
21
+ class NotImplemented < Exception; end
22
+ class NotInitialized < Exception; end
23
+ class MissingApiKey < Exception; end
24
+ end
25
+
26
+ class << self
27
+ attr_accessor :api_key
28
+
29
+ URL = 'https://amiando.com'
30
+ TEST_URL = 'https://test.amiando.com'
31
+
32
+ def production!
33
+ @production = true
34
+ end
35
+
36
+ def development!
37
+ @production = false
38
+ end
39
+
40
+ def base_url
41
+ @production ? URL : TEST_URL
42
+ end
43
+
44
+ def requests
45
+ @requests ||= []
46
+ end
47
+
48
+ def run
49
+ requests.each{ |request| hydra.queue(request) }
50
+ hydra.run
51
+ ensure
52
+ @requests = []
53
+ end
54
+
55
+ def hydra
56
+ @hydra ||= Typhoeus::Hydra.new
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,35 @@
1
+ module Amiando
2
+
3
+ ##
4
+ # http://developers.amiando.com/index.php/REST_API_ApiKey
5
+ class ApiKey < Resource
6
+
7
+ ##
8
+ # Creates an {ApiKey}.
9
+ #
10
+ # @param [Hash] possible attributes that can be set on creation.
11
+ def self.create(attributes)
12
+ raise ArgumentError.new('ApiKey name field is mandatory') unless attributes[:name]
13
+
14
+ object = new
15
+ request = post object, '/api/apiKey/create', :params => attributes
16
+
17
+ object
18
+ end
19
+
20
+ ##
21
+ # Updates an {ApiKey}.
22
+ #
23
+ # @param [Hash] possible attributes that can be updated.
24
+ def self.update(id, attributes)
25
+ object = Boolean.new(:success)
26
+ request = post object, "/api/apiKey/#{id}", :params => attributes
27
+
28
+ object
29
+ end
30
+
31
+ def populate(response_body)
32
+ extract_attributes_from(response_body, 'apiKey')
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,33 @@
1
+ module Amiando
2
+
3
+ ##
4
+ # This object is intended to be used when an api will return a boolean
5
+ # response, but due to the delayed nature of doing requests in parallel,
6
+ # can't be initialized from the beginning.
7
+ #
8
+ # After the object is populated, you can ask the result with the result
9
+ # method.
10
+ class Boolean
11
+ attr_accessor :request, :response
12
+
13
+ def initialize(response_attribute)
14
+ @response_attribute = response_attribute.to_s
15
+ end
16
+
17
+ def populate(response_body)
18
+ if response_body.key?(@response_attribute)
19
+ @result = response_body[@response_attribute]
20
+ else
21
+ raise Error::NotInitialized.new("The response doesn't have the expected attribute")
22
+ end
23
+ end
24
+
25
+ def result
26
+ if defined?(@result)
27
+ @result
28
+ else
29
+ raise Error::NotInitialized.new('Called result before the query was run')
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,131 @@
1
+ module Amiando
2
+
3
+ ##
4
+ # http://developers.amiando.com/index.php/REST_API_Events
5
+ class Event < Resource
6
+ map :host_id, :hostId
7
+ map :selected_date, :selectedDate, :type => :time
8
+ map :selected_end_date, :selectedEndDate, :type => :time
9
+ map :short_description, :shortDescription
10
+ map :event_type, :eventType
11
+ map :organisator_display_name, :organisatorDisplayName
12
+ map :partner_event_url, :partnerEventUrl
13
+ map :publish_search_engines, :publishSearchEngines
14
+ map :search_engine_tags, :searchEngineTags
15
+ map :location_description, :locationDescription
16
+ map :zip_code, :zipCode
17
+ map :creation_time, :creationTime, :type => :time
18
+ map :last_modified, :lastModified, :type => :time
19
+
20
+ ##
21
+ # Creates an event.
22
+ #
23
+ # @return [Event] will not return the full event and only the id attribute
24
+ # will be available.
25
+ def self.create(attributes)
26
+ object = new
27
+ request = post object, '/api/event/create',
28
+ :params => map_params(attributes),
29
+ :populate_method => :populate_create
30
+
31
+ object
32
+ end
33
+
34
+ ##
35
+ # Updates an event.
36
+ #
37
+ # @return [Boolean] if it was successful or not.
38
+ def self.update(id, attributes)
39
+ object = Result.new do |response_body, result|
40
+ unless response_body['success']
41
+ result.errors = response_body['errors']
42
+ end
43
+ response_body['success']
44
+ end
45
+ request = post object, "/api/event/#{id}", :params => map_params(attributes)
46
+
47
+ object
48
+ end
49
+
50
+ ##
51
+ # Fetch an event
52
+ def self.find(id)
53
+ object = new
54
+ request = get object, "/api/event/#{id}"
55
+
56
+ object
57
+ end
58
+
59
+ ##
60
+ # See if an event id exists
61
+ def self.exists?(identifier)
62
+ object = Boolean.new('exists')
63
+ request = get object, "api/event/exists",
64
+ :params => { :identifier => identifier }
65
+
66
+ object
67
+ end
68
+
69
+ ##
70
+ # Deletes an event
71
+ #
72
+ # @param [Integer] event id
73
+ #
74
+ # @return [Boolean] with the result of the operation
75
+ def self.delete(id)
76
+ object = Boolean.new('deleted')
77
+ request = do_request object, :delete, "/api/event/#{id}"
78
+
79
+ object
80
+ end
81
+
82
+ ##
83
+ # Activate an event
84
+ #
85
+ # @param [Integer] the event id
86
+ #
87
+ # @return [Result] if it was activated or not.
88
+ def self.activate(id)
89
+ object = Result.new do |response_body, result|
90
+ unless response_body['success']
91
+ result.errors = response_body['errors']
92
+ end
93
+ response_body['success']
94
+ end
95
+ request = post object, "/api/event/#{id}/activate"
96
+
97
+ object
98
+ end
99
+
100
+ ##
101
+ # Search by identifier or title.
102
+ #
103
+ # @param [Hash] a hash with 1 entry, either :identifier or :title
104
+ #
105
+ # @return [Result] with an array of ids
106
+ def self.search(by)
107
+ unless by[:identifier].nil? ^ by[:title].nil? # XOR
108
+ raise ArgumentError.new('Events can be searched either by identifier or by title, include only one.')
109
+ end
110
+
111
+ object = Result.new { |response_body| response_body['ids'] }
112
+ request = get object, '/api/event/find', :params => by
113
+
114
+ object
115
+ end
116
+
117
+ def self.find_all_by_user_id(user_id)
118
+ object = Result.new do |response_body|
119
+ response_body['events']
120
+ end
121
+ request = get object, "/api/user/#{user_id}/events"
122
+ object
123
+ end
124
+
125
+ private
126
+
127
+ def populate(response_body)
128
+ extract_attributes_from(response_body, 'event')
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,38 @@
1
+ module Amiando
2
+ class Request < Typhoeus::Request
3
+ attr_reader :object
4
+
5
+ def initialize(object, verb, path, params)
6
+ @object = object
7
+
8
+ if verb == :post
9
+ path = build_url(path, default_params)
10
+ else
11
+ path = build_url(path)
12
+ params = default_params.merge(params || {})
13
+ end
14
+
15
+ super(path, :method => verb, :params => params, :verbose => 1)
16
+ end
17
+
18
+ private
19
+
20
+ def default_params
21
+ default = {
22
+ :format => :json,
23
+ :version => 1
24
+ }
25
+ default.merge!(:apikey => Amiando.api_key) if Amiando.api_key
26
+ default
27
+ end
28
+
29
+ def build_url(url, merge_params = {})
30
+ url = URI.join(Amiando.base_url, url).to_s
31
+ unless merge_params.empty?
32
+ query_params = merge_params.map{|k,v| "#{k}=#{v}"}.join('&')
33
+ url = "#{url}?#{query_params}"
34
+ end
35
+ url
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,152 @@
1
+ module Amiando
2
+ class Resource
3
+ attr_accessor :request, :response
4
+ attr_reader :success, :attributes
5
+
6
+ class << self
7
+ def map(local, remote, options = {})
8
+ mapping[local] = remote
9
+ typecasting[local] = options[:type] if options[:type]
10
+ end
11
+
12
+ def typecasting
13
+ @@typecasting ||= {}
14
+ end
15
+
16
+ def mapping
17
+ @@mapping ||= {}
18
+ end
19
+
20
+ ##
21
+ # From { :first_name => '1', :last_name => '2' }
22
+ # to { :firstName => '1', :lastName => '2' }
23
+ def map_params(attributes)
24
+ mapped_attributes = attributes.map do |key,value|
25
+ mapped_key = mapping[key] || key
26
+ value = typecast(key, value)
27
+ [mapped_key, value]
28
+ end
29
+ Hash[mapped_attributes]
30
+ end
31
+
32
+ def reverse_map_params(attributes)
33
+ inverted_mapping = mapping.invert
34
+ mapped_attributes = attributes.map do |key,value|
35
+ key = key.to_sym
36
+ mapped_key = inverted_mapping[key] || key
37
+ value = inverse_typecast(key, value)
38
+ [mapped_key, value]
39
+ end
40
+ Hash[mapped_attributes]
41
+ end
42
+
43
+ private
44
+
45
+ def do_request(object, verb, path, options = {})
46
+ req = Request.new(object, verb, path, options[:params] || {})
47
+ object.request = req
48
+
49
+ req.on_complete do |response|
50
+
51
+ # Raise different errors depending on the return codes
52
+ case response.code
53
+ when 403
54
+ raise Error::NotAuthorized.new(response.body)
55
+ when 404
56
+ raise Error::NotFound.new(response.body)
57
+ when 503
58
+ raise Error::ServiceDown.new(response.body)
59
+ end
60
+
61
+ parsed_body = Yajl::Parser.parse(response.body)
62
+
63
+ if parsed_body['errors'] && parsed_body['errors'].include?('com.amiando.api.rest.MissingParam.apikey')
64
+ raise Error::MissingApiKey.new('This call requires an apikey')
65
+ end
66
+
67
+ object.response = response
68
+ object.send(options[:populate_method] || :populate, parsed_body)
69
+ end
70
+
71
+ Amiando.requests << req
72
+ end
73
+
74
+ def get(object, path, options = {})
75
+ do_request(object, :get, path, options)
76
+ end
77
+
78
+ def post(object, path, options = {})
79
+ do_request(object, :post, path, options)
80
+ end
81
+
82
+ def typecast(key, value)
83
+ if typecasting[key] == :time || value.is_a?(Time)
84
+ value.iso8601
85
+ else
86
+ value
87
+ end
88
+ end
89
+
90
+ def inverse_typecast(key, value)
91
+ if typecasting[key] == :time
92
+ Time.parse(value)
93
+ else
94
+ value
95
+ end
96
+ end
97
+ end
98
+
99
+ def initialize(attributes = nil)
100
+ set_attributes(attributes)
101
+ end
102
+
103
+ def [](key)
104
+ @attributes[key.to_sym]
105
+ end
106
+
107
+ def method_missing(method_name, *args, &block)
108
+ if @attributes.key?(method_name) && args.empty?
109
+ @attributes[method_name]
110
+ else
111
+ super
112
+ end
113
+ end
114
+
115
+ def id
116
+ @attributes[:id]
117
+ end
118
+
119
+ def populate(reponse_body)
120
+ raise Error::NotImplemented.new("populate method not implemented for #{self.class}")
121
+ end
122
+
123
+ def populate_create(response_body)
124
+ @attributes = {:id => response_body['id'], :errors => response_body['errors']}
125
+ @success = response_body['success']
126
+ end
127
+
128
+ def extract_attributes_from(response_body, key)
129
+ @attributes = {}
130
+
131
+ set_attributes(response_body[key])
132
+
133
+ @success = response_body['success']
134
+ end
135
+
136
+ def ==(resource)
137
+ id == resource.id
138
+ end
139
+
140
+ protected
141
+
142
+ def set_attributes(attributes)
143
+ @attributes = {}
144
+
145
+ if attributes
146
+ self.class.reverse_map_params(attributes).each do |k,v|
147
+ @attributes[k.to_sym] = v
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end