collegiatelink 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,8 +2,11 @@ require 'digest'
2
2
  require 'net/https'
3
3
  require 'net/ssh'
4
4
  require 'guid'
5
+ require 'json'
5
6
  require 'nokogiri'
6
- require 'happymapper'
7
+ require 'ostruct'
8
+ require 'representable/json'
9
+ require 'representable/xml'
7
10
  require 'socksify/http'
8
11
 
9
12
  require 'collegiatelink/response'
@@ -17,13 +20,16 @@ require 'collegiatelink/organization'
17
20
  #
18
21
  module CollegiateLink
19
22
  # Currently-supported CollegiateLink action request types
20
- ACTIONS = [
23
+ OLD_ACTIONS = [
21
24
  'organization/list',
22
25
  'organization/roster',
23
26
  #'user/memberships',
24
27
  #'user/position',
25
28
  'event/list',
26
29
  ]
30
+ NEW_ACTIONS = [
31
+ 'financetransactions',
32
+ ]
27
33
 
28
34
  # Raised when performing a CollegiateLink::Request for an action that is not
29
35
  # supported by the gem (as defined by CollegiateLink::ACTIONS).
@@ -17,7 +17,6 @@ module CollegiateLink
17
17
  }
18
18
  @opts = {
19
19
  sharedkey: sharedkey,
20
- debug: true,
21
20
  }
22
21
  @@proxy = Net::HTTP
23
22
  end
@@ -44,6 +43,15 @@ module CollegiateLink
44
43
  orgs = request('organization/list', CollegiateLink::Organization, params)
45
44
  end
46
45
 
46
+ def financetransactions(params = {})
47
+ # Default to only showing transactions in the past seven days
48
+ seven_days = 7 * 24 * 60 * 60
49
+ params[:startdate] ||= (Time.now.to_i - seven_days)
50
+ params[:startdate] = params[:startdate].to_i * 1000
51
+
52
+ transactions = request('financetransactions', CollegiateLink::FinanceTransaction, params)
53
+ end
54
+
47
55
  ##
48
56
  # Return a complete list of CollegiateLink::Event instances for your
49
57
  # institution.
@@ -80,14 +88,14 @@ module CollegiateLink
80
88
  cl_request = CollegiateLink::Request.new(action, params.merge(@params), @opts)
81
89
  cl_resp = cl_request.perform
82
90
 
83
- all_items = cl_resp.items.map { |i| model.parse(i.to_s) }
91
+ all_items = cl_resp.items.map { |i| model.parse(i) }
84
92
 
85
93
  while cl_resp.has_next_page?
86
94
  cl_request = cl_request.request_for_next_page
87
95
  cl_resp = cl_request.perform
88
- all_items += cl_resp.items.map { |i| model.parse(i.to_s) }
96
+ all_items += cl_resp.items.map { |i| model.parse(i) }
89
97
  end
90
-
98
+
91
99
  all_items
92
100
  end
93
101
  end
@@ -11,16 +11,16 @@ module CollegiateLink
11
11
  # * <tt>:street1 </tt> - String
12
12
  # * <tt>:street2 </tt> - String
13
13
  # * <tt>:type </tt> - Integer
14
- class Address
15
- include HappyMapper
16
-
17
- element :city, String
18
- element :country, String
19
- element :postalcode, String
20
- element :state, String
21
- element :street1, String
22
- element :street2, String
23
- element :type, Integer
14
+ class Address < OpenStruct
15
+ include Representable::XML
16
+
17
+ property :city
18
+ property :country
19
+ property :postalcode
20
+ property :state
21
+ property :street1
22
+ property :street2
23
+ property :type
24
24
  end
25
25
 
26
26
  ##
@@ -31,12 +31,12 @@ module CollegiateLink
31
31
  # * <tt>:id </tt> - Integer
32
32
  # * <tt>:ishidden</tt> - String
33
33
  # * <tt>:name </tt> - String
34
- class Category
35
- include HappyMapper
34
+ class Category < OpenStruct
35
+ include Representable::XML
36
36
 
37
- element :id, Integer
38
- element :ishidden, String
39
- element :name, String
37
+ property :id
38
+ property :ishidden
39
+ property :name
40
40
  end
41
41
 
42
42
  ##
@@ -54,19 +54,23 @@ module CollegiateLink
54
54
  # * <tt>:type </tt> - String
55
55
  # * <tt>:addresses </tt> - Array of CollegiateLink::Address
56
56
  # * <tt>:categories </tt> - Array of CollegiateLink::Category
57
- class Organization
58
- include HappyMapper
59
-
60
- element :id, Integer
61
- element :parentId, Integer
62
- element :name, String
63
- element :description, String
64
- element :shortName, String
65
- element :siteUrl, String
66
- element :status, String
67
- element :type, String
68
- has_many :addresses, Address
69
- has_many :categories, Category
57
+ class Organization < OpenStruct
58
+ include Representable::XML
59
+
60
+ property :id
61
+ property :parentId
62
+ property :name
63
+ property :description
64
+ property :shortName
65
+ property :siteUrl
66
+ property :status
67
+ property :type
68
+ collection :addresses
69
+ collection :categories
70
+
71
+ def self.parse(xml)
72
+ from_xml(xml.to_s)
73
+ end
70
74
  end
71
75
 
72
76
  ##
@@ -85,35 +89,70 @@ module CollegiateLink
85
89
  # * <tt>:urlSmall </tt> - String
86
90
  # * <tt>:organization</tt> - The hosting Organization
87
91
  #
88
- class Event
89
- include HappyMapper
90
-
91
- element :id, Integer
92
- element :name, String
93
- element :description, String
94
- element :startDate, Integer
95
- element :endDate, Integer
96
- element :location, String
97
- element :status, String
98
- element :urlLarge, String
99
- element :urlSmall, String
100
-
101
- has_one :organization, Organization
92
+ class Event < OpenStruct
93
+ include Representable::XML
94
+
95
+ property :id
96
+ property :name
97
+ property :description
98
+ property :startDate
99
+ property :endDate
100
+ property :location
101
+ property :status
102
+ property :urlLarge
103
+ property :urlSmall
104
+
105
+ def self.parse(xml)
106
+ from_xml(xml.to_s)
107
+ end
108
+ end
109
+
110
+ class FinanceTransaction < OpenStruct
111
+ include Representable::JSON
112
+
113
+ property :transactionId
114
+ property :transactionNumber
115
+ property :requestId
116
+ property :requestNumber
117
+ property :transactionType
118
+ property :financeTypeId
119
+ property :financeTypeName
120
+ property :financeCategoryId
121
+ property :financeCategoryName
122
+ property :accountId
123
+ property :accountName
124
+ property :originatingAccountId
125
+ property :originatingAccountName
126
+ property :originatingOrganizationId
127
+ property :originiatingOrganizationName
128
+ property :requestPayeeFirstName
129
+ property :requestPayeeLastName
130
+ property :payeeSourceFirstName
131
+ property :payeeSourceLastName
132
+ property :transactionDate # todo, make this usable as a date ("1363891642000")
133
+ property :amount
134
+ property :endingAllocationAfter
135
+ property :endingAvailableAfter
136
+ property :memo
137
+ property :reconciledStatus
138
+ property :cancelledStatus
139
+
140
+ def self.parse(hash)
141
+ new(hash)
142
+ end
102
143
  end
103
144
 
104
145
  ##
105
146
  # A position of someone in an organization
106
147
  #
107
- class Position
108
- include HappyMapper
148
+ class Position < OpenStruct
149
+ include Representable::XML
109
150
 
110
- element :name, String
111
- element :enddate, Integer
112
- element :startdate, Integer
113
- element :userstartdate, Integer
114
- element :userenddate, Integer
115
- element :positionTemplate, String
116
- element :positionType, String
151
+ property :name
152
+ property :enddate
153
+ property :startdate
154
+ property :userstartdate
155
+ property :userenddate
117
156
 
118
157
  def current?
119
158
  use_startdate = (userstartdate > 0) ? userstartdate : startdate
@@ -134,25 +173,21 @@ module CollegiateLink
134
173
  ##
135
174
  # A Member record returned by CollegiateLink
136
175
  #
137
- class Member
138
- include HappyMapper
176
+ class Member < OpenStruct
177
+ include Representable::XML
139
178
 
140
- #element :affiliation # Not sure the format of this...
141
- element :campusemail, String
142
- element :firstname, String
143
- element :id, Integer
144
- element :lastname, String
145
- element :preferredemail, String
146
- element :username, String
179
+ #property :affiliation # Not sure the format of this...
180
+ property :campusemail
181
+ property :firstname
182
+ property :id
183
+ property :lastname
184
+ property :preferredemail
185
+ property :username
147
186
 
148
- has_many :positions, Position
187
+ collection :positions, :class => CollegiateLink::Position
149
188
 
150
189
  def active_positions
151
190
  positions.keep_if { |p| p.current? }
152
191
  end
153
-
154
- def ==(other)
155
- self.id == other.id
156
- end
157
192
  end
158
193
  end
@@ -22,20 +22,28 @@ module CollegiateLink
22
22
  # * <tt>:debug</tt> - Print debug information as the request happens.
23
23
  #
24
24
  def initialize(action, params = {}, opts = {})
25
- raise UnknownAction unless ACTIONS.include?(action)
26
- raise AuthenticationException unless opts.include?(:sharedkey)
27
-
28
25
  @action = action
29
26
  @params = params
30
27
  @opts = opts
31
28
 
29
+ raise AuthenticationException unless opts.include?(:sharedkey)
30
+
31
+ if OLD_ACTIONS.include?(action)
32
+ @opts[:url_base] ||= 'https://casewestern.collegiatelink.net/ws/' % @params[:apikey]
33
+ @opts[:response_format] = 'XML'
34
+ elsif NEW_ACTIONS.include?(action)
35
+ @opts[:url_base] ||= 'https://casewestern.collegiatelink.net/api/' % @params[:apikey]
36
+ @opts[:response_format] = 'JSON'
37
+ else
38
+ raise UnknownAction, 'Action not supported!'
39
+ end
40
+
32
41
  # URL Query String Parameters
33
42
  @params[:page] ||= 1
34
- @params[:pagesize] ||= 100
35
- @params[:modelformatting] ||= 'normal'
43
+ @params[:pageSize] ||= 100
36
44
 
37
45
  # Default values for optional parameters
38
- @opts[:url_base] ||= 'https://%s.collegiatelink.net/ws/' % @params[:apikey]
46
+ @opts[:debug] ||= true
39
47
  end
40
48
 
41
49
  ##
@@ -70,7 +78,12 @@ module CollegiateLink
70
78
 
71
79
  case resp
72
80
  when Net::HTTPSuccess
73
- return parse_response(resp.body)
81
+ case @opts[:response_format]
82
+ when 'JSON'
83
+ return parse_json_response(resp.body)
84
+ when 'XML'
85
+ return parse_xml_response(resp.body)
86
+ end
74
87
  when Net::HTTPError
75
88
  raise NetworkException
76
89
  else
@@ -88,7 +101,7 @@ module CollegiateLink
88
101
 
89
102
  private
90
103
 
91
- def parse_response(body)
104
+ def parse_xml_response(body)
92
105
  d = Nokogiri::XML::Document.parse(body)
93
106
 
94
107
  # Parse exceptions
@@ -109,7 +122,13 @@ module CollegiateLink
109
122
  end
110
123
  end
111
124
 
112
- Response.new(d)
125
+ CollegiateLink::Response::XML.new(d)
126
+ end
127
+
128
+ def parse_json_response(body)
129
+ d = ::JSON.parse(body)
130
+ # Handle errors?
131
+ CollegiateLink::Response::JSON.new(d)
113
132
  end
114
133
 
115
134
  def hash(params = {})
@@ -1,30 +1,54 @@
1
1
  module CollegiateLink
2
- ##
3
- # Container for the XML gunk returned from CollegiateLink
4
- #
5
- class Response
6
- # Create the response.
7
- #
8
- # ==== Parameters:
9
- # * +document+ - The Nokogiri document of the returned XML
10
- def initialize(document)
11
- raise UnknownException unless document.xpath('//results/page')
12
-
13
- @document = document
14
- @page_size = document.xpath('//results/page/pageSize').inner_html.to_i
15
- @page_number = document.xpath('//results/page/pageNumber').inner_html.to_i
16
- @total_items = document.xpath('//results/page/totalItems').inner_html.to_i
17
- @total_pages = document.xpath('//results/page/totalPages').inner_html.to_i
2
+ module Response
3
+ module Common
4
+ # Utility method to determine if the request has another page to retrieve.
5
+ def has_next_page?
6
+ @page_number < @total_pages
7
+ end
18
8
  end
19
9
 
20
- # Extract the items from the response. Returns a Nokogiri NodeSet.
21
- def items
22
- @document.xpath('//results/page/items/*')
10
+ ##
11
+ # Container for the XML gunk returned from CollegiateLink
12
+ #
13
+ class XML
14
+ include CollegiateLink::Response::Common
15
+
16
+ # Create the response.
17
+ #
18
+ # ==== Parameters:
19
+ # * +document+ - The Nokogiri document of the returned XML
20
+ def initialize(document)
21
+ raise UnknownException unless document.xpath('//results/page')
22
+
23
+ @document = document
24
+ @page_size = document.xpath('//results/page/pageSize').inner_html.to_i
25
+ @page_number = document.xpath('//results/page/pageNumber').inner_html.to_i
26
+ @total_items = document.xpath('//results/page/totalItems').inner_html.to_i
27
+ @total_pages = document.xpath('//results/page/totalPages').inner_html.to_i
28
+ end
29
+
30
+ # Extract the items from the response. Returns a Nokogiri NodeSet.
31
+ def items
32
+ @document.xpath('//results/page/items/*')
33
+ end
23
34
  end
24
35
 
25
- # Utility method to determine if the request has another page to retrieve.
26
- def has_next_page?
27
- @page_number < @total_pages
36
+ class JSON
37
+ include CollegiateLink::Response::Common
38
+
39
+ def initialize(document)
40
+ raise UnknownException unless document["items"]
41
+
42
+ @document = document
43
+ @page_size = document["pageSize"]
44
+ @page_number = document["pageNumber"]
45
+ @total_items = document["totalItems"]
46
+ @total_pages = document["totalPages"]
47
+ end
48
+
49
+ def items
50
+ @document["items"]
51
+ end
28
52
  end
29
53
  end
30
54
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: collegiatelink
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-19 00:00:00.000000000 Z
12
+ date: 2012-03-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: guid
@@ -44,7 +44,7 @@ dependencies:
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
46
  - !ruby/object:Gem::Dependency
47
- name: happymapper
47
+ name: representable
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
@@ -138,7 +138,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
138
138
  version: '0'
139
139
  requirements: []
140
140
  rubyforge_project:
141
- rubygems_version: 1.8.24
141
+ rubygems_version: 1.8.23
142
142
  signing_key:
143
143
  specification_version: 3
144
144
  summary: CollegiateLink Client Gem