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.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +64 -0
- data/README.rdoc +44 -0
- data/Rakefile +32 -0
- data/fellowshipone_api.gemspec +25 -0
- data/lib/api/api_object.rb +141 -0
- data/lib/api/communication.rb +59 -0
- data/lib/api/contribution.rb +97 -0
- data/lib/api/contribution_list.rb +57 -0
- data/lib/api/fund.rb +40 -0
- data/lib/api/fund_list.rb +53 -0
- data/lib/api/household.rb +50 -0
- data/lib/api/household_list.rb +78 -0
- data/lib/api/member_household_list.rb +73 -0
- data/lib/api/mergeable_household_list.rb +79 -0
- data/lib/api/mergeable_person_list.rb +110 -0
- data/lib/api/person.rb +169 -0
- data/lib/api/person_list.rb +85 -0
- data/lib/api/search.rb +55 -0
- data/lib/auto_load.rb +17 -0
- data/lib/common.rb +76 -0
- data/lib/exceptions.rb +5 -0
- data/lib/fellowship_one.rb +54 -0
- data/lib/oauth_monkey_patch.rb +13 -0
- data/lib/readers/api_reader.rb +34 -0
- data/lib/readers/communication_reader.rb +19 -0
- data/lib/readers/contribution_list_reader.rb +37 -0
- data/lib/readers/contribution_reader.rb +18 -0
- data/lib/readers/fund_list_reader.rb +13 -0
- data/lib/readers/fund_reader.rb +14 -0
- data/lib/readers/household_list_reader.rb +62 -0
- data/lib/readers/household_reader.rb +18 -0
- data/lib/readers/member_household_list_reader.rb +27 -0
- data/lib/readers/person_list_reader.rb +37 -0
- data/lib/readers/person_reader.rb +20 -0
- data/lib/writers/api_writer.rb +64 -0
- data/lib/writers/communication_writer.rb +27 -0
- data/lib/writers/contribution_writer.rb +28 -0
- data/lib/writers/household_writer.rb +30 -0
- data/lib/writers/person_writer.rb +64 -0
- data/spec/api/person_spec.rb +21 -0
- data/spec/functional/fellowship_one_spec.rb +17 -0
- data/spec/readers/api_reader_spec.rb +7 -0
- data/spec/spec_helper.rb +47 -0
- data/spec/vcr_setup.rb +5 -0
- data/spec/writers/api_writer_spec.rb +7 -0
- 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
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
|