fellowshipone-api 0.6.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.
Files changed (51) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile +14 -0
  6. data/Gemfile.lock +64 -0
  7. data/README.rdoc +44 -0
  8. data/Rakefile +32 -0
  9. data/fellowshipone_api.gemspec +25 -0
  10. data/lib/api/api_object.rb +141 -0
  11. data/lib/api/communication.rb +59 -0
  12. data/lib/api/contribution.rb +97 -0
  13. data/lib/api/contribution_list.rb +57 -0
  14. data/lib/api/fund.rb +40 -0
  15. data/lib/api/fund_list.rb +53 -0
  16. data/lib/api/household.rb +50 -0
  17. data/lib/api/household_list.rb +78 -0
  18. data/lib/api/member_household_list.rb +73 -0
  19. data/lib/api/mergeable_household_list.rb +79 -0
  20. data/lib/api/mergeable_person_list.rb +110 -0
  21. data/lib/api/person.rb +169 -0
  22. data/lib/api/person_list.rb +85 -0
  23. data/lib/api/search.rb +55 -0
  24. data/lib/auto_load.rb +17 -0
  25. data/lib/common.rb +76 -0
  26. data/lib/exceptions.rb +5 -0
  27. data/lib/fellowship_one.rb +54 -0
  28. data/lib/oauth_monkey_patch.rb +13 -0
  29. data/lib/readers/api_reader.rb +34 -0
  30. data/lib/readers/communication_reader.rb +19 -0
  31. data/lib/readers/contribution_list_reader.rb +37 -0
  32. data/lib/readers/contribution_reader.rb +18 -0
  33. data/lib/readers/fund_list_reader.rb +13 -0
  34. data/lib/readers/fund_reader.rb +14 -0
  35. data/lib/readers/household_list_reader.rb +62 -0
  36. data/lib/readers/household_reader.rb +18 -0
  37. data/lib/readers/member_household_list_reader.rb +27 -0
  38. data/lib/readers/person_list_reader.rb +37 -0
  39. data/lib/readers/person_reader.rb +20 -0
  40. data/lib/writers/api_writer.rb +64 -0
  41. data/lib/writers/communication_writer.rb +27 -0
  42. data/lib/writers/contribution_writer.rb +28 -0
  43. data/lib/writers/household_writer.rb +30 -0
  44. data/lib/writers/person_writer.rb +64 -0
  45. data/spec/api/person_spec.rb +21 -0
  46. data/spec/functional/fellowship_one_spec.rb +17 -0
  47. data/spec/readers/api_reader_spec.rb +7 -0
  48. data/spec/spec_helper.rb +47 -0
  49. data/spec/vcr_setup.rb +5 -0
  50. data/spec/writers/api_writer_spec.rb +7 -0
  51. metadata +129 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4ef90aa299f36b4c0a571d002270b2ab0b3581b3
4
+ data.tar.gz: adcedccde6a8ecec28f5ba2d645be7ae5f8226fc
5
+ SHA512:
6
+ metadata.gz: 6d6ecceef36ccef3d72218b6ab39413eceedf8b094632f5c3f9852cd59215b8e61b69d4ae15bea024e01a21e480ba7ed960af3dd3170d80a602d2fddb45e9185
7
+ data.tar.gz: 9a7eecf24d55cf41ca22f1a1ff476cc4e0c1787ecd6e8485a5ee8332cb0f83daba2a3c371dba74150a43cfbb073ec8e8acf1cb27f9c0675893ede4603608865b
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ fellowshipone-api-*.gem
2
+ access_token.yml
3
+ access_token_marshal.txt
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ fellowshipone-api
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.0.0-p247
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'typhoeus', '0.6.6'
4
+ gem 'json'
5
+ gem 'oauth_weshays', '0.4.8.pre2'
6
+
7
+ group :development, :test do
8
+ gem 'rspec'
9
+ gem 'debugger'
10
+ gem 'factory_girl'
11
+
12
+ gem 'vcr'
13
+ gem 'webmock', '1.9' # Currently does not work with Typhoeus 0.4.2 - THIS SUCKS!
14
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,64 @@
1
+ GEM
2
+ remote: http://rubygems.org/
3
+ specs:
4
+ activesupport (4.0.1)
5
+ i18n (~> 0.6, >= 0.6.4)
6
+ minitest (~> 4.2)
7
+ multi_json (~> 1.3)
8
+ thread_safe (~> 0.1)
9
+ tzinfo (~> 0.3.37)
10
+ addressable (2.3.5)
11
+ atomic (1.1.14)
12
+ columnize (0.3.6)
13
+ crack (0.4.1)
14
+ safe_yaml (~> 0.9.0)
15
+ debugger (1.6.2)
16
+ columnize (>= 0.3.1)
17
+ debugger-linecache (~> 1.2.0)
18
+ debugger-ruby_core_source (~> 1.2.3)
19
+ debugger-linecache (1.2.0)
20
+ debugger-ruby_core_source (1.2.3)
21
+ diff-lcs (1.2.5)
22
+ ethon (0.6.1)
23
+ ffi (>= 1.3.0)
24
+ mime-types (~> 1.18)
25
+ factory_girl (4.3.0)
26
+ activesupport (>= 3.0.0)
27
+ ffi (1.9.3)
28
+ i18n (0.6.5)
29
+ json (1.8.1)
30
+ mime-types (1.25)
31
+ minitest (4.7.5)
32
+ multi_json (1.8.2)
33
+ oauth_weshays (0.4.8.pre2)
34
+ rspec (2.14.1)
35
+ rspec-core (~> 2.14.0)
36
+ rspec-expectations (~> 2.14.0)
37
+ rspec-mocks (~> 2.14.0)
38
+ rspec-core (2.14.7)
39
+ rspec-expectations (2.14.4)
40
+ diff-lcs (>= 1.1.3, < 2.0)
41
+ rspec-mocks (2.14.4)
42
+ safe_yaml (0.9.7)
43
+ thread_safe (0.1.3)
44
+ atomic
45
+ typhoeus (0.6.6)
46
+ ethon (~> 0.6.1)
47
+ tzinfo (0.3.38)
48
+ vcr (2.7.0)
49
+ webmock (1.9.0)
50
+ addressable (>= 2.2.7)
51
+ crack (>= 0.1.7)
52
+
53
+ PLATFORMS
54
+ ruby
55
+
56
+ DEPENDENCIES
57
+ debugger
58
+ factory_girl
59
+ json
60
+ oauth_weshays (= 0.4.8.pre2)
61
+ rspec
62
+ typhoeus (= 0.6.6)
63
+ vcr
64
+ webmock (= 1.9)
data/README.rdoc ADDED
@@ -0,0 +1,44 @@
1
+ = FellowshipOne API
2
+
3
+ This Ruby project is an API wrapper for the FellowshipOne API (https://developer.fellowshipone.com/)
4
+
5
+
6
+ == Install / Setup
7
+
8
+ Installing the gem
9
+
10
+ gem install fellowshipone-api
11
+
12
+
13
+ To add it to your Gemfile
14
+
15
+ gem 'fellowshipone-api', :require => 'fellowshipone'
16
+
17
+
18
+ == Example usage
19
+
20
+ Checkout the examples folder.
21
+
22
+
23
+ == Additional resources
24
+
25
+ * FellowshipOne API: https://developer.fellowshipone.com/docs/
26
+ * FellowshipOne Forum: https://developer.fellowshipone.com/forum/
27
+
28
+
29
+ == License
30
+
31
+ This project is released under the MIT license (see LICENSE).
32
+
33
+ This project is maintained by Wes Hays (https://github.com/weshays).
34
+
35
+
36
+ == Contributors
37
+
38
+ Chad Feller: https://github.com/cfeller
39
+ Taylor Brooks: https://github.com/taylorbrooks
40
+
41
+
42
+ == Want to Contribute?
43
+
44
+ If you would like to get involved in this project, then please fork the project. Make changes, add features, write some tests, and then send a pull request.
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+
4
+ desc 'Default: run specs.'
5
+ task :default => :spec
6
+ task :test => :spec
7
+
8
+ desc "Run specs"
9
+ RSpec::Core::RakeTask.new do |t|
10
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
11
+ # Put spec opts in a file named .rspec in root
12
+ end
13
+
14
+
15
+ desc "Generate code coverage"
16
+ RSpec::Core::RakeTask.new(:coverage) do |t|
17
+ t.pattern = "./spec/**/*_spec.rb" # don't need this, it's default.
18
+ t.rcov = true
19
+ t.rcov_opts = ['--exclude', 'spec']
20
+ end
21
+
22
+
23
+
24
+ namespace :docs do
25
+
26
+ desc 'Build the docs for the FellowshipOne API.'
27
+ task :build do
28
+ system('rm -rf doc')
29
+ system('yardoc --no-private --protected lib/**/*.rb')
30
+ end
31
+
32
+ end
@@ -0,0 +1,25 @@
1
+ Gem::Specification.new do |s|
2
+ PROJECT_GEM = 'fellowshipone-api'
3
+ PROJECT_GEM_VERSION = '0.6.0'
4
+
5
+ s.name = PROJECT_GEM
6
+ s.version = PROJECT_GEM_VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+
9
+ s.homepage = 'https://github.com/weshays/fellowshipone-api-ruby'
10
+ s.rubyforge_project = 'Project on www.github.com'
11
+ s.authors = ['Wes Hays', 'Chad Feller']
12
+ s.email = ['weshays@gbdev.com','feller@cs.unr.edu']
13
+
14
+ s.summary = 'Ruby gem/plugin to interact with the FellowshipOne API (https://developer.fellowshipone.com/).'
15
+ s.description = 'Ruby gem/plugin to interact with the FellowshipOne API (https://developer.fellowshipone.com/). Checkout the project on github for more detail.'
16
+
17
+ s.add_dependency('typhoeus', '0.6.6')
18
+ s.add_dependency('oauth_weshays', '0.4.8.pre2')
19
+
20
+
21
+ s.files = `git ls-files`.split("\n").delete_if { |f| !(f =~ /^examples/).nil? }
22
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
+ s.require_paths = ["lib"]
25
+ end
@@ -0,0 +1,141 @@
1
+ module FellowshipOne
2
+
3
+ # This class is the base class for all FellowshipOne objects and is meant to be inherited.
4
+ #
5
+ class ApiObject
6
+ attr_reader :error_messages, :marked_for_destruction
7
+
8
+
9
+ # Used to specify a list of getters and setters.
10
+ def self.f1_attr_accessor(*vars)
11
+ @__f1_attributes ||= []
12
+ @__f1_attributes.concat(vars)
13
+ attr_accessor(*vars)
14
+ end
15
+
16
+
17
+ # A list of f1_attr_accessors that have been specified.
18
+ def self.__f1_attributes
19
+ @__f1_attributes
20
+ end
21
+
22
+ # Initializes the current object from the JSON data that was loaded into the Hash.
23
+ #
24
+ # @param object_attributes A Hash of values to load into the current object.
25
+ def initialize_from_json_object(object_attributes)
26
+ if object_attributes.is_a?( Hash )
27
+ object_attributes.each do |key, value|
28
+
29
+ method_to_call = "#{_attr_underscore(key.to_s)}="
30
+ if method_to_call.chars.first == "@"
31
+ method_to_call.reverse!.chop!.reverse!
32
+ end
33
+
34
+ if respond_to?(method_to_call)
35
+ self.send(method_to_call, value)
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+
42
+
43
+ # # Returns the status of the current object.
44
+ # def is_deleted?
45
+ # @_deleted ||= false
46
+ # end
47
+
48
+ # Gets the current object's attributes in a Hash.
49
+ #
50
+ # @return A hash of all the attributes.
51
+ def to_attributes
52
+ vals = {}
53
+ #vals = {:marked_for_destruction => self.is_deleted?} if self.is_deleted?
54
+ self.class.__f1_attributes.each do |tca|
55
+ rep = self.send(tca)
56
+ if rep.class == Array
57
+ rep.collect! { |r| r.respond_to?(:to_attributes) ? r.to_attributes : r }
58
+ end
59
+ vals[_f1ize(tca)] = rep
60
+ end
61
+ _map_fields(vals)
62
+ vals
63
+ end
64
+
65
+
66
+ # Sets the current object's attributes from a hash
67
+ def set_attributes(attribute_data)
68
+ attribute_data.each { |key, value| self.send("#{key}=", value) if self.respond_to?("#{key}=") }
69
+ end
70
+
71
+
72
+ # Save this object.
73
+ #
74
+ # @return True on success, otherwise false.
75
+ def save
76
+ raise "@writer_object not set for #{self.class}" if @writer_object.nil?
77
+ writer = @writer_object.new(self.to_attributes)
78
+ result = writer.save_object
79
+ if result === false
80
+ @error_messages = writer.error_messages
81
+ else
82
+ rkey = self._default_result_key
83
+ self.initialize_from_json_object(rkey.nil? ? result : result[rkey])
84
+ end
85
+ result === false ? false : true
86
+ end
87
+
88
+
89
+ # # Delete this object.
90
+ # #
91
+ # # @return True on success, otherwise false.
92
+ # def delete
93
+ # writer = @writer_object.new(self.to_attributes)
94
+ # result = writer.delete_object
95
+ # if result === false
96
+ # @error_messages = writer.error_messages
97
+ # else
98
+ # @_deleted = true
99
+ # end
100
+ # result === false ? false : true
101
+ # end
102
+
103
+
104
+ # This method should be overwritten in the ApiObject subclass.
105
+ def _field_map
106
+ {}
107
+ end
108
+
109
+ def _default_result_key
110
+ self.class.to_s.split('::').last.downcase
111
+ end
112
+
113
+ private
114
+
115
+ # Used for mapping FellowshipOne fields that may not match the naming or camelcase
116
+ # used, or that is generated.
117
+ def _map_fields(fields)
118
+ self._field_map.each do |key1, key2|
119
+ fields[key2.to_s] = fields[key1.to_s]
120
+ fields.delete(key1.to_s)
121
+ end
122
+ end
123
+
124
+
125
+ def _attr_underscore(str)
126
+ str.gsub(/::/, '/')
127
+ .gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
128
+ .gsub(/([a-z\d])([A-Z])/,'\1_\2')
129
+ .tr("-", "_")
130
+ .downcase
131
+ end
132
+
133
+ def _f1ize(term)
134
+ term.to_s.split('_').inject([]) { |buffer, e| buffer.push(buffer.empty? ? e : e.capitalize) }.join
135
+ end
136
+
137
+ end
138
+
139
+ end
140
+
141
+
@@ -0,0 +1,59 @@
1
+ module FellowshipOne
2
+
3
+ class Communication < ApiObject
4
+
5
+ f1_attr_accessor :id,
6
+ :uri,
7
+ :household,
8
+ :person,
9
+ :communication_type,
10
+ :communication_general_type,
11
+ :communication_value,
12
+ :search_communication_value,
13
+ :preferred,
14
+ :communication_comment,
15
+ :created_date,
16
+ :last_updated_date
17
+
18
+ # Load the communication by the specified ID.
19
+ #
20
+ # @param communication_id The ID of the communication to load.
21
+ #
22
+ # Returns a new Communication object.
23
+ def self.load_by_id(communication_id)
24
+ reader = CommunicationReader.new(nil, communication_id)
25
+ self.new(reader)
26
+ end
27
+
28
+ # Constructor.
29
+ #
30
+ # @param person_id The ID of the person to load the communication for.
31
+ # @param reader (optional) The object that has the data. This can be a CommunicationReader or Hash object.
32
+ def initialize(person_id, reader = nil)
33
+ @writer_object = CommunicationWriter
34
+ if reader.is_a?(CommunicationReader)
35
+ initialize_from_json_object(reader.load_feed['communication'])
36
+ elsif reader.is_a?(Hash)
37
+ initialize_from_json_object(reader)
38
+ else # new
39
+ reader = CommunicationReader.new(person_id, nil)
40
+ initialize_from_json_object(reader.load_new['communication'])
41
+ end
42
+ end
43
+
44
+ def household_id
45
+ self.household['@id']
46
+ end
47
+
48
+ def individual_id
49
+ self.person['@id']
50
+ end
51
+ alias_method :person_id, :individual_id
52
+
53
+ def _field_map
54
+ {:id => '@id',
55
+ :uri => '@uri'}
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,97 @@
1
+ module FellowshipOne
2
+
3
+ class Contribution < ApiObject
4
+
5
+ f1_attr_accessor :id,
6
+ :uri,
7
+ :old_id,
8
+ :account_reference,
9
+ :amount,
10
+ :fund,
11
+ :sub_fund,
12
+ :pledge_drive,
13
+ :household,
14
+ :person,
15
+ :account,
16
+ :reference_image,
17
+ :batch,
18
+ :activity_instance,
19
+ :contribution_type,
20
+ :contribution_sub_type,
21
+ :received_date,
22
+ :transmit_date,
23
+ :return_date,
24
+ :retransmit_date,
25
+ :gl_post_date,
26
+ :is_split,
27
+ :address_verification,
28
+ :memo,
29
+ :stated_value,
30
+ :true_value,
31
+ :thank,
32
+ :thanked_date,
33
+ :is_matched,
34
+ :created_date,
35
+ :created_by_person,
36
+ :last_updated_date,
37
+ :last_updated_by_person
38
+
39
+ # Load the contribution by the specified ID.
40
+ #
41
+ # @param contribution_id The ID of the contribution to load.
42
+ #
43
+ # Returns a new Contribution object.
44
+ def self.load_by_id(contribution_id)
45
+ reader = ContributionReader.new(contribution_id)
46
+ self.new(reader)
47
+ end
48
+
49
+ # Constructor.
50
+ #
51
+ # @param reader (optional) The object that has the data. This can be a ContributionReader or Hash object.
52
+ def initialize(reader = nil)
53
+ @writer_object = ContributionWriter
54
+ if reader.is_a?(ContributionReader)
55
+ initialize_from_json_object(reader.load_feed['contributionReceipt'])
56
+ elsif reader.is_a?(Hash)
57
+ initialize_from_json_object(reader)
58
+ else # new
59
+ reader = ContributionReader.new
60
+ initialize_from_json_object(reader.load_new['contributionReceipt'])
61
+ end
62
+ end
63
+
64
+
65
+ def fund_id
66
+ self.fund['@id']
67
+ end
68
+
69
+ def household_id
70
+ self.household['@id']
71
+ end
72
+
73
+ def individual_id
74
+ self.person['@id']
75
+ end
76
+ alias_method :person_id, :individual_id
77
+
78
+ def amount_cents
79
+ (self.amount.to_f * 100).to_i
80
+ end
81
+
82
+ def instrument_type
83
+ self.contribution_type['name']
84
+ end
85
+
86
+ def _default_result_key
87
+ 'contributionReceipt'
88
+ end
89
+
90
+ def _field_map
91
+ {:id => '@id',
92
+ :uri => '@uri',
93
+ :oldId => '@oldID'}
94
+ end
95
+ end
96
+
97
+ end