fellowshipone-api 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|