shelby-arena-api 0.1.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.
@@ -0,0 +1,49 @@
1
+ module ShelbyArena
2
+
3
+ class FundList
4
+
5
+ include Enumerable
6
+
7
+ # attr_reader :count, :page_number, :total_records, :additional_pages
8
+
9
+
10
+ # Constructor.
11
+ #
12
+ # @param options A hash of options for loading the list.
13
+ #
14
+ # Options:
15
+ # :reader - (optional) The Reader to use to load the data.
16
+ def initialize(options = {})
17
+ reader = options[:reader] || ShelbyArena::FundListReader.new(options)
18
+ @json_data = reader.load_data['FundListResult']['Funds']['Fund']
19
+ end
20
+
21
+ # Get the specified fund.
22
+ #
23
+ # @param index The index of the fund to get.
24
+ #
25
+ # @return Fund
26
+ def [](index)
27
+ Fund.new( @json_data[index] ) unless @json_data[index].nil?
28
+ end
29
+
30
+
31
+ # This method is needed for Enumerable.
32
+ def each &block
33
+ @json_data.each{ |fund| yield( Fund.new(fund) )}
34
+ end
35
+
36
+ # Alias the count method
37
+ alias :size :count
38
+
39
+
40
+ # Checks if the list is empty.
41
+ #
42
+ # @return True on empty, false otherwise.
43
+ def empty?
44
+ self.count == 0 ? true : false
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -0,0 +1,79 @@
1
+ module ShelbyArena
2
+
3
+ class Person < ApiObject
4
+ attribute :addresses, Array[Address]
5
+ attribute :campus_id, Integer
6
+ attribute :campus_name, String
7
+ attribute :family_id, Integer
8
+ attribute :family_member_role_id, Integer
9
+ attribute :family_member_role_value, String
10
+ attribute :gender, String
11
+ attribute :first_name, String
12
+ attribute :nick_name, String
13
+ attribute :last_name, String
14
+ attribute :birth_date, Date
15
+ attribute :age, Integer
16
+ attribute :home_phone, String
17
+ attribute :cell_phone, String
18
+ attribute :first_active_email, String
19
+ attribute :member_status_id, Integer
20
+ attribute :member_status_value, String
21
+ attribute :person_guid, String
22
+ attribute :person_id, Integer
23
+ attribute :person_link, String
24
+ attribute :record_status_value, String
25
+ attribute :bloblink, String
26
+ attribute :area_name, String
27
+
28
+
29
+ # Loads the user by the specified ID.
30
+ #
31
+ # @param person_id The ID of the person to load.
32
+ #
33
+ # Returns a new Person object.
34
+ def self.load_by_id(person_id)
35
+ reader = PersonReader.new(person_id)
36
+ self.new(reader)
37
+ rescue
38
+ nil
39
+ end
40
+
41
+
42
+ # Constructor.
43
+ #
44
+ # @param reader (optional) The object that has the data. This can be a PersonReader or Hash object.
45
+ # @param options (optional) Options for including more information.
46
+ def initialize(reader = nil, options = {})
47
+ @writer_object = PersonWriter
48
+ if reader.is_a?(PersonReader)
49
+ initialize_from_json_object(reader.load_data['Person'])
50
+ elsif reader.is_a?(Hash)
51
+ initialize_from_json_object(reader)
52
+ else # new empty
53
+ raise 'Not sure about this one yet'
54
+ # reader = PersonReader.new
55
+ # initialize_from_json_object(reader.load_new['person'])
56
+ end
57
+ end
58
+
59
+
60
+ # def is_head_of_household?
61
+ # # I do not see a way to get this yet.
62
+ # end
63
+
64
+
65
+ def family_role
66
+ self.family_member_role_value.blank? ? 'Other' : self.family_member_role_value
67
+ end
68
+
69
+
70
+ def is_child?
71
+ self.family_member_role_value.downcase == 'child'
72
+ end
73
+
74
+ def email_address
75
+ self.first_active_email
76
+ end
77
+ end
78
+
79
+ end
@@ -0,0 +1,53 @@
1
+ module ShelbyArena
2
+
3
+ class PersonList
4
+
5
+ include Enumerable
6
+
7
+ # Constructor.
8
+ #
9
+ # @param options A hash of options for loading the list.
10
+ #
11
+ # Options:
12
+ # :reader - (optional) The Reader to use to load the data.
13
+ def initialize(options = {})
14
+ reader = options[:reader] || ShelbyArena::PersonListReader.new(options)
15
+ @json_data = reader.load_data['PersonListResult']['Persons']['Person']
16
+ end
17
+
18
+ # Get the specified person.
19
+ #
20
+ # @param index The index of the person to get.
21
+ #
22
+ # @return [Person]
23
+ def [](index)
24
+ Person.new( @json_data[index] ) unless @json_data[index].nil?
25
+ end
26
+
27
+
28
+ # This method is needed for Enumerable.
29
+ def each &block
30
+ @json_data.each{ |person| yield( Person.new(person) )}
31
+ end
32
+
33
+ # Alias the count method
34
+ alias :size :count
35
+
36
+ # Checks if the list is empty.
37
+ #
38
+ # @return True on empty, false otherwise.
39
+ def empty?
40
+ #@json_data['person'].empty?
41
+ self.count == 0 ? true : false
42
+ end
43
+
44
+ # Access to the raw JSON data. This method is needed for merging lists.
45
+ #
46
+ # @returns Raw JSON data.
47
+ def raw_data
48
+ @json_data
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -0,0 +1,17 @@
1
+ module ShelbyArena
2
+
3
+ class ShelbySession < ApiObject
4
+ attribute :id, String
5
+ attribute :expires_at, DateTime
6
+
7
+ # Constructor.
8
+ #
9
+ # @param response_data Session response data from the Shelby service.
10
+ def initialize(response_data)
11
+ self.id = response_data['ApiSession']['SessionID']
12
+ self.expires_at = response_data['ApiSession']['DateExpires']
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,17 @@
1
+ module ShelbyArena
2
+
3
+ require SHELBY_ARENA_LIB_DIR + '/exceptions.rb'
4
+
5
+ api_path = SHELBY_ARENA_LIB_DIR + '/api/'
6
+ require api_path + 'api_object.rb'
7
+ Dir["#{api_path}/*.rb"].each { |f| require(f) }
8
+
9
+ readers_path = SHELBY_ARENA_LIB_DIR + '/readers/'
10
+ require readers_path + 'api_reader.rb'
11
+ Dir["#{readers_path}/*.rb"].each { |f| require(f) }
12
+
13
+ writers_path = SHELBY_ARENA_LIB_DIR + '/writers/'
14
+ require writers_path + 'api_writer.rb'
15
+ Dir["#{writers_path}/*.rb"].each { |f| require(f) }
16
+
17
+ end
@@ -0,0 +1,75 @@
1
+ module ShelbyArena
2
+
3
+ def self.request_session
4
+ response = Typhoeus::Request.post(ShelbyArena::Api.service_url+'/login', {body: {username: ShelbyArena::Api.username, password: ShelbyArena::Api.password, api_key: ShelbyArena::Api.api_key}})
5
+ raise ShelbyArenaExceptions::UnableToConnectToShelbyArena.new(response.body) unless response.success?
6
+ self._xml2json(response.body)
7
+ end
8
+
9
+
10
+ def self.api_request(method, path, params = {}, body = nil)
11
+ url = [ShelbyArena::Api.service_url, path].join('/')
12
+ mparams = params.merge({api_session: ShelbyArena::Api.session_key})
13
+ mparams = mparams.merge({api_sig: self._generate_api_signature(path, params)})
14
+
15
+ response =
16
+ case method
17
+ when :post
18
+ raise 'Shelby POST not tested yet'
19
+ #Typhoeus::Request.post(url, {:headers => headers, :body => body})
20
+ when :get
21
+ Typhoeus::Request.get(url, params: mparams)
22
+ when :put
23
+ raise 'Shelby PUT not tested yet'
24
+ # Typhoeus::Request.put(url, {:headers => headers, :body => body})
25
+ when :delete
26
+ raise 'Shelby DELETE not tested yet'
27
+ # Typhoeus::Request.delete(url, {:headers => headers, :params => params})
28
+ end
29
+
30
+ if !response.success?
31
+ if response.code > 0
32
+ raise ShelbyArenaExceptions::UnableToConnectToShelbyArena.new(response.body)
33
+ else
34
+ begin
35
+ error_messages = JSON.parse(response.body)['error_message']
36
+ rescue
37
+ response_code_desc = response.headers.partition("\r\n")[0].sub(/^\S+/, '') rescue nil
38
+ raise ShelbyArenaExceptions::UnknownErrorConnectingToShelbyArena.new("Unknown error when connecting to Shelby Arena.#{response_code_desc}")
39
+ else
40
+ raise ShelbyArenaExceptions::ShelbyArenaResponseError.new(error_messages)
41
+ end
42
+ end
43
+ end
44
+
45
+ response
46
+ end
47
+
48
+
49
+ def self._xml2json(xml)
50
+ # {KeepRoot: true, ForceArray: false, SuppressEmpty: true} were set to
51
+ # maximize compatibility with Hash.from_xml, used previously.
52
+ #
53
+ XmlSimple.xml_in(xml, {KeepRoot: true, ForceArray: false, SuppressEmpty: true})
54
+ end
55
+
56
+
57
+ def self._generate_api_signature(path, params)
58
+ get_vars = ''
59
+ if params.to_a.size > 0
60
+ get_vars = '?' + params.to_a.sort.collect { |kv_pair| "#{kv_pair[0]}=#{kv_pair[1].to_s}" }.join('&').downcase
61
+ end
62
+ utoken = get_vars.empty? ? '?' : '&'
63
+ Digest::MD5.hexdigest("#{ShelbyArena::Api.api_secret}_#{path.downcase}#{get_vars}#{utoken}api_session=#{ShelbyArena::Api.session_key}")
64
+ end
65
+
66
+
67
+ # This is a helper method
68
+ def self.attr_underscore(str)
69
+ str.gsub(/::/, '/')
70
+ .gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
71
+ .gsub(/([a-z\d])([A-Z])/,'\1_\2')
72
+ .tr("-", "_")
73
+ .downcase
74
+ end
75
+ end
@@ -0,0 +1,5 @@
1
+ module ShelbyArenaExceptions
2
+ class UnableToConnectToShelbyArena < StandardError; end
3
+ class UnknownErrorConnectingToShelbyArena< StandardError; end
4
+ class ShelbyArenaResponseError < StandardError; end
5
+ end
@@ -0,0 +1,26 @@
1
+
2
+ module ShelbyArena
3
+
4
+ # This class is the base class for all ShelbyArena objects and is meant to be inherited.
5
+ class ApiReader
6
+ attr_reader :headers
7
+
8
+ # Loads the data.
9
+ #
10
+ # @return the data loaded in a JSON object.
11
+ def load_data
12
+ @url_data_params ||= {}
13
+ return _load_data(@url_data_path, @url_data_params)
14
+ end
15
+
16
+ private
17
+
18
+ def _load_data(url_data_path, url_data_params)
19
+ response = ShelbyArena::api_request(:get, url_data_path, url_data_params)
20
+ @headers = response.headers
21
+ ShelbyArena::_xml2json(response.body)
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,28 @@
1
+ module ShelbyArena
2
+
3
+ class ContributionListReader < ApiReader
4
+
5
+ # Constructor.
6
+ def initialize(options = {})
7
+ # page = options[:page] || 1
8
+ # per_page = options[:per_page] || 100
9
+
10
+ @url_data_params = {}
11
+ valid_fields.each { |field| @url_data_params[field] = options[ShelbyArena::attr_underscore(field).to_sym] unless options[ShelbyArena::attr_underscore(field).to_sym].nil? }
12
+ @url_data_path = 'contribution/list'
13
+ end
14
+
15
+ def valid_fields
16
+ %W(Active
17
+ CanPledge
18
+ EndDate
19
+ FundId
20
+ FundName
21
+ OnlineName
22
+ StartDate
23
+ TaxDeductible).sort
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,19 @@
1
+ module ShelbyArena
2
+
3
+ class ContributionReader < ApiReader
4
+
5
+ # Constructor.
6
+ #
7
+ # @param contribution_id (optional) The ID of the contribution to load.
8
+ def initialize(contribution_id = nil)
9
+ if contribution_id.nil?
10
+ raise 'The create endpoint is not known yet.'
11
+ @url_new_data_path = nil # Not sure yet
12
+ else
13
+ @url_data_path = "contribution/#{contribution_id}"
14
+ end
15
+ end
16
+
17
+ end
18
+
19
+ end
@@ -0,0 +1,21 @@
1
+ module ShelbyArena
2
+
3
+ class FamilyReader < ApiReader
4
+
5
+ # Constructor.
6
+ #
7
+ # @param family_id (optional) The ID of the family to load.
8
+ def initialize(family_id = nil)
9
+ if family_id.nil?
10
+ raise 'The create endpoint is not known yet.'
11
+ @url_new_data_path = nil # Not sure yet
12
+ else
13
+ @url_data_path = "family/#{family_id}"
14
+ end
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+
21
+
@@ -0,0 +1,28 @@
1
+ module ShelbyArena
2
+
3
+ class FundListReader < ApiReader
4
+
5
+ # Constructor.
6
+ def initialize(options = {})
7
+ # page = options[:page] || 1
8
+ # per_page = options[:per_page] || 100
9
+
10
+ @url_data_params = {}
11
+ valid_fields.each { |field| @url_data_params[field] = options[ShelbyArena::attr_underscore(field).to_sym] unless options[ShelbyArena::attr_underscore(field).to_sym].nil? }
12
+ @url_data_path = 'fund/list'
13
+ end
14
+
15
+ def valid_fields
16
+ %W(Active
17
+ CanPledge
18
+ EndDate
19
+ FundId
20
+ FundName
21
+ OnlineName
22
+ StartDate
23
+ TaxDeductible).sort
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,19 @@
1
+ module ShelbyArena
2
+
3
+ class FundReader < ApiReader
4
+
5
+ # Constructor.
6
+ #
7
+ # @param fund_id (optional) The ID of the fund to load.
8
+ def initialize(fund_id = nil)
9
+ if fund_id.nil?
10
+ raise 'The create endpoint is not known yet.'
11
+ @url_new_data_path = nil # Not sure yet
12
+ else
13
+ @url_data_path = "fund/#{fund_id}"
14
+ end
15
+ end
16
+
17
+ end
18
+
19
+ end