collegiatelink 0.0.5 → 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.
@@ -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