osm 0.0.26 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +57 -0
- data/README.md +13 -7
- data/lib/osm.rb +47 -22
- data/lib/osm/activity.rb +52 -57
- data/lib/osm/api.rb +115 -1031
- data/lib/osm/api_access.rb +73 -36
- data/lib/osm/due_badges.rb +27 -12
- data/lib/osm/evening.rb +118 -55
- data/lib/osm/event.rb +275 -17
- data/lib/osm/flexi_record.rb +131 -0
- data/lib/osm/grouping.rb +37 -15
- data/lib/osm/member.rb +100 -41
- data/lib/osm/model.rb +95 -0
- data/lib/osm/register.rb +177 -0
- data/lib/osm/section.rb +163 -71
- data/lib/osm/term.rb +135 -21
- data/spec/osm/activity_spec.rb +7 -4
- data/spec/osm/api_access_spec.rb +44 -36
- data/spec/osm/api_spec.rb +32 -1147
- data/spec/osm/due_badges_spec.rb +8 -1
- data/spec/osm/evening_spec.rb +119 -54
- data/spec/osm/event_spec.rb +363 -13
- data/spec/osm/flexi_record_spec.rb +128 -0
- data/spec/osm/grouping_spec.rb +9 -5
- data/spec/osm/member_spec.rb +111 -36
- data/spec/osm/model_spec.rb +140 -0
- data/spec/osm/osm_spec.rb +7 -31
- data/spec/osm/register_spec.rb +103 -0
- data/spec/osm/section_spec.rb +208 -92
- data/spec/osm/term_spec.rb +164 -28
- data/spec/spec_helper.rb +22 -0
- data/version.rb +1 -1
- metadata +22 -29
- data/lib/osm/event_attendance.rb +0 -55
- data/lib/osm/flexi_record_data.rb +0 -51
- data/lib/osm/flexi_record_field.rb +0 -42
- data/lib/osm/register_data.rb +0 -64
- data/lib/osm/register_field.rb +0 -42
- data/lib/osm/role.rb +0 -133
- data/spec/osm/api_strangeness_spec.rb +0 -83
- data/spec/osm/event_attendance_spec.rb +0 -34
- data/spec/osm/flexi_record_data_spec.rb +0 -40
- data/spec/osm/flexi_record_field_spec.rb +0 -23
- data/spec/osm/register_data_spec.rb +0 -35
- data/spec/osm/register_field_spec.rb +0 -24
- data/spec/osm/role_spec.rb +0 -118
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,60 @@
|
|
1
|
+
## Version 0.1.0
|
2
|
+
|
3
|
+
* Configuration is through Osm::configure not Osm::Api.configure and it takes a different Hash
|
4
|
+
* Api.authorize returns a different Hash
|
5
|
+
* Removal of Osm::Api methods:
|
6
|
+
* get\_*
|
7
|
+
* update\_*
|
8
|
+
* create\_*
|
9
|
+
* EventAttendance is now Event::Attendance
|
10
|
+
* Removal of Osm::Role
|
11
|
+
* Osm::Section now has two new required attributes group\_id and group\_name
|
12
|
+
* long\_name and full\_name methods should be replaced with something similar to "#{section.name} (#{section.group\_name})" in your own code
|
13
|
+
* Section has a class method fetch\_user\_permissions(api) which returns a Hash (section\_id to permissions Hash)
|
14
|
+
* Activity now has class method get(api, activity\_id)
|
15
|
+
* ApiAccess: now has class methods
|
16
|
+
* get\_all(api, section)
|
17
|
+
* get(api, section, for\_api)
|
18
|
+
* get\_ours(api, section) -> actually just calls get(api, section, api)
|
19
|
+
* DueBadges now has a class method get(api, section)
|
20
|
+
* Evening now has class methods:
|
21
|
+
* get\_programme(api, section\_id, term\_id)
|
22
|
+
* create(api, parameters)
|
23
|
+
* Evening now has instance methods:
|
24
|
+
* update(api)
|
25
|
+
* get\_badge\_requirements(api, evening)
|
26
|
+
* Event now has class methods:
|
27
|
+
* get\_for\_section(api, section)
|
28
|
+
* get(api, section, event\_id)
|
29
|
+
* create(api)
|
30
|
+
* Event now has instance methods:
|
31
|
+
* update(api)
|
32
|
+
* delete(api)
|
33
|
+
* get\_attendance(api)
|
34
|
+
* add\_field(api, label)
|
35
|
+
* Event now has a fields attribute
|
36
|
+
* Event::Attendance has instance method update(api, field\_id)
|
37
|
+
* FlexiRecord has class methods:
|
38
|
+
* get\_fields(api, section, flexi\_record\_id)
|
39
|
+
* get\_data(api, section, flexi\_record\_id, term)
|
40
|
+
* Grouping now has a class method get\_for\_section(api, section)
|
41
|
+
* Member now has a class method to get\_for\_section(api, section\_id, term\_id)
|
42
|
+
* Register now has class methods:
|
43
|
+
* get\_structure(api, section)
|
44
|
+
* get\_attendance(api, section)
|
45
|
+
* update\_attendance(data)
|
46
|
+
* Section now has class methods:
|
47
|
+
* get\_all(api)
|
48
|
+
* get(api, section\_id)
|
49
|
+
* Section now has instance method get\_notepad(api)
|
50
|
+
* Term now has class methods:
|
51
|
+
* get\_all(api)
|
52
|
+
* get(api, term\_id)
|
53
|
+
* get\_for\_section(api, section\_id)
|
54
|
+
* get\_current\_term\_for\_section(api, section\_id)
|
55
|
+
* create(api, parameters)
|
56
|
+
* Term now has instance method update(api)
|
57
|
+
|
1
58
|
## Version 0.0.26
|
2
59
|
|
3
60
|
* Register - Update attendance
|
data/README.md
CHANGED
@@ -31,13 +31,19 @@ Configure the gem during the initalization of the app (e.g. if using rails then
|
|
31
31
|
|
32
32
|
```ruby
|
33
33
|
ActionDispatch::Callbacks.to_prepare do
|
34
|
-
Osm::
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
Osm::configure(
|
35
|
+
:api => {
|
36
|
+
:default_site => :osm, # or :ogm
|
37
|
+
:osm => { # or :ogm (both an :osm and :ogm config are allowed
|
38
|
+
:id => 'YOU WILL BE GIVEN THIS BY ED AT OSM',
|
39
|
+
:token => 'YOU WILL BE GIVEN THIS BY ED AT OSM',
|
40
|
+
:name => 'YOU WILL GIVE THIS TO ED AT OSM',
|
41
|
+
},
|
42
|
+
},
|
43
|
+
:cache => {
|
44
|
+
:cache => Rails.cache,
|
45
|
+
},
|
46
|
+
)
|
41
47
|
end
|
42
48
|
```
|
43
49
|
|
data/lib/osm.rb
CHANGED
@@ -6,23 +6,56 @@ require 'httparty'
|
|
6
6
|
|
7
7
|
|
8
8
|
module Osm
|
9
|
-
|
9
|
+
class Error < Exception; end
|
10
|
+
class ConnectionError < Error; end
|
11
|
+
class Forbidden < Error; end
|
12
|
+
class ArgumentIsInvalid < ArgumentError; end
|
13
|
+
class ObjectIsInvalid < Error; end
|
14
|
+
|
15
|
+
private
|
16
|
+
OSM_EPOCH = '1970-01-01'
|
17
|
+
OSM_EPOCH_HUMAN = '1970-01-01'
|
10
18
|
OSM_DATE_FORMAT = '%Y-%m-%d'
|
11
19
|
OSM_TIME_FORMAT = '%H:%M:%S'
|
12
20
|
OSM_DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'
|
21
|
+
OSM_DATE_FORMAT_HUMAN = '%d/%m/%Y'
|
22
|
+
OSM_DATETIME_FORMAT_HUMAN = '%d/%m/%Y %H:%M:%S'
|
13
23
|
OSM_TIME_REGEX = /\A(?:[0-1][0-9]|2[0-3]):[0-5][0-9]\Z/
|
14
|
-
OSM_DATE_REGEX = /\A
|
24
|
+
OSM_DATE_REGEX = /\A(?:\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1]))|(?:(?:0?[1-9]|[1-2][0-9]|3[0-1])\/(?:0?[1-9]|1[0-2])\/\d{2}|\d{4})\Z/
|
15
25
|
end
|
16
26
|
|
17
27
|
require File.join(File.dirname(__FILE__), '..', 'version')
|
18
28
|
Dir[File.join(File.dirname(__FILE__) , '*_validator.rb')].each {|file| require file }
|
29
|
+
require File.join(File.dirname(__FILE__), 'osm', 'model')
|
19
30
|
Dir[File.join(File.dirname(__FILE__) , 'osm', '*.rb')].each {|file| require file }
|
20
31
|
|
21
32
|
|
22
33
|
module Osm
|
23
|
-
|
24
|
-
|
25
|
-
|
34
|
+
|
35
|
+
# Configure the options used by classes in the module
|
36
|
+
# @param [Hash] options
|
37
|
+
# @option options [Hash] :api Default options for accessing the API
|
38
|
+
# @option options[:api] [Symbol] :default_site wether to use OSM (if :osm) or OGM (if :ogm) by default
|
39
|
+
# @option options[:api] [Hash] :osm (optional but :osm_api or :ogm_api must be present) the api data for OSM
|
40
|
+
# @option options[:api][:osm] [String] :id the apiid given to you for using the OSM id
|
41
|
+
# @option options[:api][:osm] [String] :token the token which goes with the above api
|
42
|
+
# @option options[:api][:osm] [String] :name the name displayed in the External Access tab of OSM
|
43
|
+
# @option options[:api] [Hash] :ogm (optional but :osm_api or :ogm_api must be present) the api data for OGM
|
44
|
+
# @option options[:api][:ogm] [String] :id the apiid given to you for using the OGM id
|
45
|
+
# @option options[:api][:ogm] [String] :token the token which goes with the above api
|
46
|
+
# @option options[:api][:ogm] [String] :name the name displayed in the External Access tab of OGM
|
47
|
+
# @option options[:api] [Boolean] :debug if true debugging info is output (optional, default = false)
|
48
|
+
# @option options [Hash] :cache_config (optional) How classes in the module will cache data. Whilst this is optional you should remember that caching is required to use the OSM API.
|
49
|
+
# @option options[:cache] [Class] :cache An instance of a cache class, must provide the methods (exist?, delete, write, read), for details see Rails.cache.
|
50
|
+
# @option options[:cache] [Fixnum] :ttl (optional, default = 30.minutes) The default TTL value for the cache, note that some items are cached for twice this time and others are cached for half this time (in seconds)
|
51
|
+
# @option options[:cache] [String] :prepend_to_key (optional, default = 'OSMAPI') Text to prepend to the key used to store data in the cache
|
52
|
+
# @return nil
|
53
|
+
def self.configure(options)
|
54
|
+
Osm::Model.configure(options[:cache])
|
55
|
+
Osm::Api.configure(options[:api])
|
56
|
+
nil
|
57
|
+
end
|
58
|
+
|
26
59
|
|
27
60
|
private
|
28
61
|
def self.make_array_of_symbols(array)
|
@@ -31,21 +64,8 @@ module Osm
|
|
31
64
|
end
|
32
65
|
end
|
33
66
|
|
34
|
-
def self.find_current_term_id(api, section_id, data={})
|
35
|
-
terms = api.get_terms(data)
|
36
|
-
|
37
|
-
# Return the term we are currently in
|
38
|
-
unless terms.nil?
|
39
|
-
terms.each do |term|
|
40
|
-
return term.id if (term.section_id == section_id) && term.current?
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
raise Error, 'There is no current term for the section.'
|
45
|
-
end
|
46
|
-
|
47
67
|
def self.make_datetime(date, time, options={})
|
48
|
-
date = nil if date.nil? || date.empty? || (
|
68
|
+
date = nil if date.nil? || date.empty? || (!options[:ignore_epoch] && epoch_date?(date))
|
49
69
|
time = nil if time.nil? || time.empty?
|
50
70
|
if (!date.nil? && !time.nil?)
|
51
71
|
begin
|
@@ -55,7 +75,7 @@ module Osm
|
|
55
75
|
end
|
56
76
|
elsif !date.nil?
|
57
77
|
begin
|
58
|
-
return DateTime.strptime(date, OSM_DATE_FORMAT)
|
78
|
+
return DateTime.strptime(date, (date.include?('-') ? OSM_DATE_FORMAT : OSM_DATE_FORMAT_HUMAN))
|
59
79
|
rescue ArgumentError
|
60
80
|
return nil
|
61
81
|
end
|
@@ -75,9 +95,9 @@ module Osm
|
|
75
95
|
|
76
96
|
|
77
97
|
def self.parse_date(date, options={})
|
78
|
-
return nil if date.nil? || date.empty? || (
|
98
|
+
return nil if date.nil? || date.empty? || (!options[:ignore_epoch] && epoch_date?(date))
|
79
99
|
begin
|
80
|
-
return Date.strptime(date, OSM_DATE_FORMAT)
|
100
|
+
return Date.strptime(date, (date.include?('-') ? OSM_DATE_FORMAT : OSM_DATE_FORMAT_HUMAN))
|
81
101
|
rescue ArgumentError
|
82
102
|
return nil
|
83
103
|
end
|
@@ -102,4 +122,9 @@ module Osm
|
|
102
122
|
hash_out
|
103
123
|
end
|
104
124
|
|
125
|
+
|
126
|
+
def self.epoch_date?(date)
|
127
|
+
[OSM_EPOCH, OSM_EPOCH_HUMAN].include?(date)
|
128
|
+
end
|
129
|
+
|
105
130
|
end # Module
|
data/lib/osm/activity.rb
CHANGED
@@ -1,13 +1,10 @@
|
|
1
1
|
module Osm
|
2
2
|
|
3
|
-
class Activity
|
3
|
+
class Activity < Osm::Model
|
4
4
|
class Badge; end # Ensure the constant exists for the validators
|
5
5
|
class File; end # Ensure the constant exists for the validators
|
6
6
|
class Version; end # Ensure the constant exists for the validators
|
7
7
|
|
8
|
-
include ::ActiveAttr::MassAssignmentSecurity
|
9
|
-
include ::ActiveAttr::Model
|
10
|
-
|
11
8
|
# @!attribute [rw] id
|
12
9
|
# @return [Fixnum] the id for the activity
|
13
10
|
# @!attribute [rw] version
|
@@ -70,7 +67,9 @@ module Osm
|
|
70
67
|
attribute :files, :default => []
|
71
68
|
attribute :badges, :default => []
|
72
69
|
|
73
|
-
attr_accessible :id, :version, :group_id, :user_id, :title, :description, :resources, :instructions,
|
70
|
+
attr_accessible :id, :version, :group_id, :user_id, :title, :description, :resources, :instructions,
|
71
|
+
:running_time, :location, :shared, :rating, :editable, :deletable, :used, :versions,
|
72
|
+
:sections, :tags, :files, :badges
|
74
73
|
|
75
74
|
validates_numericality_of :id, :only_integer=>true, :greater_than=>0
|
76
75
|
validates_numericality_of :version, :only_integer=>true, :greater_than_or_equal_to=>0
|
@@ -88,7 +87,6 @@ module Osm
|
|
88
87
|
validates_inclusion_of :deletable, :in => [true, false]
|
89
88
|
validates_inclusion_of :location, :in => [:indoors, :outdoors, :both], :message => 'is not a valid location'
|
90
89
|
|
91
|
-
|
92
90
|
validates :sections, :array_of => {:item_type => Symbol}
|
93
91
|
validates :tags, :array_of => {:item_type => String}
|
94
92
|
validates :badges, :array_of => {:item_type => Osm::Activity::Badge, :item_valid => true}
|
@@ -96,14 +94,26 @@ module Osm
|
|
96
94
|
validates :versions, :array_of => {:item_type => Osm::Activity::Version, :item_valid => true}
|
97
95
|
|
98
96
|
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
97
|
+
# Get activity details
|
98
|
+
# @param [Osm::Api] api The api to use to make the request
|
99
|
+
# @param [Fixnum] activity_id the activity ID
|
100
|
+
# @param [Fixnum] version the version of the activity to retreive, if nil the latest version will be assumed
|
101
|
+
# @!macro options_get
|
102
|
+
# @return [Osm::Activity]
|
103
|
+
def self.get(api, activity_id, version=nil, options={})
|
104
|
+
cache_key = ['activity', activity_id]
|
102
105
|
|
106
|
+
if !options[:no_cache] && cache_exist?(api, [*cache_key, version]) # TODO work out permission check
|
107
|
+
return cache_read(api, [*cache_key, version])
|
108
|
+
end
|
109
|
+
|
110
|
+
data = nil
|
111
|
+
if version.nil?
|
112
|
+
data = api.perform_query("programme.php?action=getActivity&id=#{activity_id}")
|
113
|
+
else
|
114
|
+
data = api.perform_query("programme.php?action=getActivity&id=#{activity_id}&version=#{version}")
|
115
|
+
end
|
103
116
|
|
104
|
-
# Initialize a new Activity from api data
|
105
|
-
# @param [Hash] data the hash of data provided by the API
|
106
|
-
def self.from_api(data)
|
107
117
|
attributes = {}
|
108
118
|
attributes[:id] = Osm::to_i_or_nil(data['details']['activityid'])
|
109
119
|
attributes[:version] = data['details']['version'].to_i
|
@@ -128,19 +138,45 @@ module Osm
|
|
128
138
|
|
129
139
|
# Populate Arrays
|
130
140
|
(data['files'].is_a?(Array) ? data['files'] : []).each do |file_data|
|
131
|
-
attributes[:files].push File.
|
141
|
+
attributes[:files].push File.new(
|
142
|
+
:id => Osm::to_i_or_nil(file_data['fileid']),
|
143
|
+
:activity_id => Osm::to_i_or_nil(file_data['activityid']),
|
144
|
+
:file_name => file_data['filename'],
|
145
|
+
:name => file_data['name']
|
146
|
+
)
|
132
147
|
end
|
133
148
|
(data['badges'].is_a?(Array) ? data['badges'] : []).each do |badge_data|
|
134
|
-
attributes[:badges].push Badge.
|
149
|
+
attributes[:badges].push Badge.new(
|
150
|
+
:activity_id => Osm::to_i_or_nil(badge_data['activityid']),
|
151
|
+
:section_type => badge_data['section'].to_sym,
|
152
|
+
:type => badge_data['badgetype'].to_sym,
|
153
|
+
:badge => badge_data['badge'],
|
154
|
+
:requirement => badge_data['columnname'],
|
155
|
+
:label => badge_data['label']
|
156
|
+
)
|
135
157
|
end
|
136
158
|
(data['versions'].is_a?(Array) ? data['versions'] : []).each do |version_data|
|
137
|
-
attributes[:versions].push Version.
|
159
|
+
attributes[:versions].push Version.new(
|
160
|
+
:version => Osm::to_i_or_nil(version_data['value']),
|
161
|
+
:created_by => Osm::to_i_or_nil(version_data['userid']),
|
162
|
+
:created_by_name => version_data['firstname'],
|
163
|
+
:label => version_data['label']
|
164
|
+
)
|
138
165
|
end
|
139
166
|
|
140
|
-
|
167
|
+
activity = Osm::Activity.new(attributes)
|
168
|
+
|
169
|
+
cache_write(api, [*cache_key, nil], activity) if version.nil?
|
170
|
+
cache_write(api, [*cache_key, version], activity)
|
171
|
+
return activity
|
141
172
|
end
|
142
173
|
|
143
174
|
|
175
|
+
# @!method initialize
|
176
|
+
# Initialize a new Term
|
177
|
+
# @param [Hash] attributes the hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
|
178
|
+
|
179
|
+
|
144
180
|
private
|
145
181
|
class File
|
146
182
|
include ::ActiveAttr::MassAssignmentSecurity
|
@@ -167,23 +203,10 @@ module Osm
|
|
167
203
|
validates_presence_of :file_name
|
168
204
|
validates_presence_of :name
|
169
205
|
|
170
|
-
|
171
206
|
# @!method initialize
|
172
207
|
# Initialize a new Term
|
173
208
|
# @param [Hash] attributes the hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
|
174
209
|
|
175
|
-
|
176
|
-
# Initialize a new File from api data
|
177
|
-
# @param [Hash] data the hash of data provided by the API
|
178
|
-
def self.from_api(data)
|
179
|
-
return new({
|
180
|
-
:id => Osm::to_i_or_nil(data['fileid']),
|
181
|
-
:activity_id => Osm::to_i_or_nil(data['activityid']),
|
182
|
-
:file_name => data['filename'],
|
183
|
-
:name => data['name']
|
184
|
-
})
|
185
|
-
end
|
186
|
-
|
187
210
|
end # Class Activity::File
|
188
211
|
|
189
212
|
class Badge
|
@@ -221,25 +244,10 @@ module Osm
|
|
221
244
|
record.errors.add(attr, 'must be a Symbol') unless value.is_a?(Symbol)
|
222
245
|
end
|
223
246
|
|
224
|
-
|
225
247
|
# @!method initialize
|
226
248
|
# Initialize a new Badge
|
227
249
|
# @param [Hash] attributes the hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
|
228
250
|
|
229
|
-
|
230
|
-
# Initialize a new Badge from api data
|
231
|
-
# @param [Hash] data the hash of data provided by the API
|
232
|
-
def self.from_api(data)
|
233
|
-
return new({
|
234
|
-
:activity_id => Osm::to_i_or_nil(data['activityid']),
|
235
|
-
:section_type => data['section'].to_sym,
|
236
|
-
:type => data['badgetype'].to_sym,
|
237
|
-
:badge => data['badge'],
|
238
|
-
:requirement => data['columnname'],
|
239
|
-
:label => data['label']
|
240
|
-
})
|
241
|
-
end
|
242
|
-
|
243
251
|
end # Class Activity::Badge
|
244
252
|
|
245
253
|
class Version
|
@@ -267,23 +275,10 @@ module Osm
|
|
267
275
|
validates_presence_of :created_by_name
|
268
276
|
validates_presence_of :label
|
269
277
|
|
270
|
-
|
271
278
|
# @!method initialize
|
272
279
|
# Initialize a new Version
|
273
280
|
# @param [Hash] attributes the hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
|
274
281
|
|
275
|
-
|
276
|
-
# Initialize a new Version from api data
|
277
|
-
# @param [Hash] data the hash of data provided by the API
|
278
|
-
def self.from_api(data)
|
279
|
-
return new({
|
280
|
-
:version => Osm::to_i_or_nil(data['value']),
|
281
|
-
:created_by => Osm::to_i_or_nil(data['userid']),
|
282
|
-
:created_by_name => data['firstname'],
|
283
|
-
:label => data['label']
|
284
|
-
})
|
285
|
-
end
|
286
|
-
|
287
282
|
end # Class Activity::Version
|
288
283
|
|
289
284
|
end # Class Activity
|
data/lib/osm/api.rb
CHANGED
@@ -1,1060 +1,187 @@
|
|
1
|
-
# @!macro [new] options_get
|
2
|
-
# @param [Hash] options
|
3
|
-
# @option options [Boolean] :no_cache (optional) if true then the data will be retreived from OSM not the cache
|
4
|
-
|
5
|
-
# @!macro [new] options_api_data
|
6
|
-
# @param [Hash] api_data - DEPRECATED (DO NOT USE THIS OPTION)
|
7
|
-
# @option api_data [String] 'userid' (optional) the OSM userid to make the request as
|
8
|
-
# @option api_data [String] 'secret' (optional) the OSM secret belonging to the above user
|
9
|
-
|
10
|
-
|
11
1
|
module Osm
|
12
2
|
|
13
3
|
class Api
|
4
|
+
|
5
|
+
# Default options
|
6
|
+
@@site = nil # Used as the defult value for api_site in new instances
|
7
|
+
@site = nil # Used to make requests from an instance
|
8
|
+
@@debug = false # Puts helpful information whilst connected to OSM/OGM
|
9
|
+
@@api_details = {:osm=>{}, :ogm=>{}} # API details - [:osm | :ogm] [:id | :token | :name]
|
14
10
|
|
15
|
-
@@default_cache_ttl = 30 * 60 # The default caching time for responses from OSM (in seconds)
|
16
|
-
# Some things will only be cached for half this time
|
17
|
-
# Whereas others will be cached for twice this time
|
18
|
-
# Most items however will be cached for this time
|
19
11
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
# Initialize a new API connection
|
26
|
-
# If passing user details then both must be passed
|
27
|
-
# @param [String] userid osm userid of the user to act as
|
28
|
-
# @param [String] secret osm secret of the user to act as
|
29
|
-
# @param [Symbol] site wether to use OSM (:scout) or OGM (:guide), defaults to the value set for the class
|
30
|
-
# @return nil
|
31
|
-
def initialize(userid=nil, secret=nil, site=@@api_site)
|
32
|
-
raise ArgumentError, 'You must pass a secret if you are passing a userid' if secret.nil? && !userid.nil?
|
33
|
-
raise ArgumentError, 'You must pass a userid if you are passing a secret' if userid.nil? && !secret.nil?
|
34
|
-
raise ArgumentError, 'site is invalid, if passed it should be either :scout or :guide' unless [:scout, :guide].include?(site)
|
12
|
+
BASE_URLS = {
|
13
|
+
:osm => 'https://www.onlinescoutmanager.co.uk',
|
14
|
+
:ogm => 'http://www.onlineguidemanager.co.uk',
|
15
|
+
}
|
35
16
|
|
36
|
-
@base_url = 'https://www.onlinescoutmanager.co.uk' if site == :scout
|
37
|
-
@base_url = 'http://www.onlineguidemanager.co.uk' if site == :guide
|
38
|
-
set_user(userid, secret)
|
39
|
-
nil
|
40
|
-
end
|
41
17
|
|
42
18
|
# Configure the API options used by all instances of the class
|
43
19
|
# @param [Hash] options
|
44
|
-
# @option options [
|
45
|
-
# @option options [
|
46
|
-
# @option options [String] :
|
47
|
-
# @option options [
|
48
|
-
# @option options [
|
49
|
-
# @option options [
|
50
|
-
# @option options [String] :
|
51
|
-
# @option options [
|
20
|
+
# @option options [Symbol] :default_site wether to use OSM (if :osm) or OGM (if :ogm)
|
21
|
+
# @option options [Hash] :osm (optional but :osm_api or :ogm_api must be present) the api data for OSM
|
22
|
+
# @option options[:osm] [String] :id the apiid given to you for using the OSM id
|
23
|
+
# @option options[:osm] [String] :token the token which goes with the above api
|
24
|
+
# @option options[:osm] [String] :name the name displayed in the External Access tab of OSM
|
25
|
+
# @option options [Hash] :ogm (optional but :osm_api or :ogm_api must be present) the api data for OGM
|
26
|
+
# @option options[:ogm] [String] :id the apiid given to you for using the OGM id
|
27
|
+
# @option options[:ogm] [String] :token the token which goes with the above api
|
28
|
+
# @option options[:ogm] [String] :name the name displayed in the External Access tab of OGM
|
29
|
+
# @option options [Boolean] :debug if true debugging info is output (optional, default = false)
|
52
30
|
# @return nil
|
53
31
|
def self.configure(options)
|
54
|
-
raise ArgumentError, ':
|
55
|
-
raise ArgumentError, ':
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
32
|
+
raise ArgumentError, ':default_site does not exist in options hash or is invalid, this should be set to either :osm or :ogm' unless [:osm, :ogm].include?(options[:default_site])
|
33
|
+
raise ArgumentError, ':osm and/or :ogm must be present' if options[:osm].nil? && options[:ogm].nil?
|
34
|
+
[:osm, :ogm].each do |api_key|
|
35
|
+
if options[api_key]
|
36
|
+
api_data = options[api_key]
|
37
|
+
raise ArgumentError, ":#{api_key} must be a Hash" unless api_data.is_a?(Hash)
|
38
|
+
[:id, :token, :name].each do |key|
|
39
|
+
raise ArgumentError, ":#{api_key} must contain a key :#{key}" if api_data[key].nil?
|
40
|
+
end
|
62
41
|
end
|
63
42
|
end
|
64
43
|
|
65
|
-
@@
|
66
|
-
@@api_token = options[:api_token].to_s
|
67
|
-
@@api_name = options[:api_name].to_s
|
68
|
-
@@api_site = options[:api_site]
|
69
|
-
@@default_cache_ttl = options[:default_cache_ttl].to_i unless options[:default_cache_ttl].nil?
|
70
|
-
@@cache_prepend_to_key = options[:cache_prepend_to_key].to_s unless options[:cache_prepend_to_key].nil?
|
71
|
-
@@cache = options[:cache]
|
44
|
+
@@site = options[:default_site]
|
72
45
|
@@debug = !!options[:debug]
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
# Get the API ID used in this class
|
77
|
-
# @return [String] the API ID
|
78
|
-
def self.api_id
|
79
|
-
return @@api_id
|
80
|
-
end
|
81
|
-
|
82
|
-
# Get the API name displayed in the External Access tab of OSM
|
83
|
-
# @return [String] the API name
|
84
|
-
def self.api_name
|
85
|
-
return @@api_name
|
86
|
-
end
|
87
|
-
|
88
|
-
# Get the userid and secret to be able to act as a certain user on the OSM system
|
89
|
-
# Also set's the 'current user'
|
90
|
-
# @param [String] email the login email address of the user on OSM
|
91
|
-
# @param [String] password the login password of the user on OSM
|
92
|
-
# @return [Hash] a hash containing the following keys:
|
93
|
-
# * 'userid' - the userid to use in future requests
|
94
|
-
# * 'secret' - the secret to use in future requests
|
95
|
-
def authorize(email, password)
|
96
|
-
api_data = {
|
97
|
-
'email' => email,
|
98
|
-
'password' => password,
|
46
|
+
@@api_details = {
|
47
|
+
:osm => (options[:osm] || {}),
|
48
|
+
:ogm => (options[:ogm] || {}),
|
99
49
|
}
|
100
|
-
|
101
|
-
set_user(data['userid'], data['secret'])
|
102
|
-
return data
|
103
|
-
end
|
104
|
-
|
105
|
-
# Set the OSM user to make future requests as
|
106
|
-
# @param [String] userid the OSM userid to use (get this using the authorize method)
|
107
|
-
# @param [String] secret the OSM secret to use (get this using the authorize method)
|
108
|
-
def set_user(userid, secret)
|
109
|
-
@userid = userid
|
110
|
-
@secret = secret
|
111
|
-
end
|
112
|
-
|
113
|
-
|
114
|
-
# Get the user's roles
|
115
|
-
# @!macro options_get
|
116
|
-
# @!macro options_api_data
|
117
|
-
# @return [Array<Osm::Role>]
|
118
|
-
def get_roles(options={}, api_data={})
|
119
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
120
|
-
cache_key = "roles-#{api_data[:userid] || @userid}"
|
121
|
-
|
122
|
-
if !options[:no_cache] && cache_exist?(cache_key)
|
123
|
-
return cache_read(cache_key)
|
124
|
-
end
|
125
|
-
|
126
|
-
data = perform_query('api.php?action=getUserRoles', api_data)
|
127
|
-
|
128
|
-
result = Array.new
|
129
|
-
data.each do |item|
|
130
|
-
role = Osm::Role.from_api(item)
|
131
|
-
result.push role
|
132
|
-
cache_write("section-#{role.section.id}", role.section, :expires_in => @@default_cache_ttl*2)
|
133
|
-
self.user_can_access :section, role.section.id, api_data
|
134
|
-
end
|
135
|
-
cache_write(cache_key, result, :expires_in => @@default_cache_ttl*2)
|
136
|
-
|
137
|
-
return result
|
138
|
-
end
|
139
|
-
|
140
|
-
# Get the user's notepads
|
141
|
-
# @!macro options_get
|
142
|
-
# @!macro options_api_data
|
143
|
-
# @return [Hash] a hash (keys are section IDs, values are a string)
|
144
|
-
def get_notepads(options={}, api_data={})
|
145
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
146
|
-
cache_key = "notepads-#{api_data[:userid] || @userid}"
|
147
|
-
|
148
|
-
if !options[:no_cache] && cache_exist?(cache_key)
|
149
|
-
return cache_read(cache_key)
|
150
|
-
end
|
151
|
-
|
152
|
-
notepads = perform_query('api.php?action=getNotepads', api_data)
|
153
|
-
return {} unless notepads.is_a?(Hash)
|
154
|
-
|
155
|
-
data = {}
|
156
|
-
notepads.each do |key, value|
|
157
|
-
data[key.to_i] = value
|
158
|
-
cache_write("notepad-#{key}", value, :expires_in => @@default_cache_ttl*2)
|
159
|
-
end
|
160
|
-
|
161
|
-
cache_write(cache_key, data, :expires_in => @@default_cache_ttl*2)
|
162
|
-
return data
|
163
|
-
end
|
164
|
-
|
165
|
-
# Get the notepad for a specified section
|
166
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to get the notepad for
|
167
|
-
# @!macro options_get
|
168
|
-
# @!macro options_api_data
|
169
|
-
# @return nil if an error occured or the user does not have access to that section
|
170
|
-
# @return [String] the content of the notepad otherwise
|
171
|
-
def get_notepad(section, options={}, api_data={})
|
172
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
173
|
-
section_id = id_for_section(section)
|
174
|
-
cache_key = "notepad-#{section_id}"
|
175
|
-
|
176
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:section, section_id, api_data)
|
177
|
-
return cache_read(cache_key)
|
178
|
-
end
|
179
|
-
|
180
|
-
notepads = get_notepads(options, api_data)
|
181
|
-
return nil unless notepads.is_a? Hash
|
182
|
-
|
183
|
-
notepads.each_key do |key|
|
184
|
-
return notepads[key] if key == section_id
|
185
|
-
end
|
186
|
-
|
187
|
-
return nil
|
188
|
-
end
|
189
|
-
|
190
|
-
# Get the section (and its configuration)
|
191
|
-
# @param [Fixnum] section_id the section id of the required section
|
192
|
-
# @!macro options_get
|
193
|
-
# @!macro options_api_data
|
194
|
-
# @return nil if an error occured or the user does not have access to that section
|
195
|
-
# @return [Osm::Section]
|
196
|
-
def get_section(section_id, options={}, api_data={})
|
197
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
198
|
-
cache_key = "section-#{section_id}"
|
199
|
-
|
200
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:section, section_id, api_data)
|
201
|
-
return cache_read(cache_key)
|
202
|
-
end
|
203
|
-
|
204
|
-
roles = get_roles(options, api_data)
|
205
|
-
return nil unless roles.is_a? Array
|
206
|
-
|
207
|
-
roles.each do |role|
|
208
|
-
return role.section if role.section.id == section_id
|
209
|
-
end
|
210
|
-
|
211
|
-
return nil
|
212
|
-
end
|
213
|
-
|
214
|
-
# Get the groupings (e.g. patrols, sixes, lodges) for a given section
|
215
|
-
# @param [Osm::Section, Fixnum] section the section to get the groupings for
|
216
|
-
# @!macro options_get
|
217
|
-
# @!macro options_api_data
|
218
|
-
# @return [Array<Osm::Grouping>]
|
219
|
-
def get_groupings(section, options={}, api_data={})
|
220
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
221
|
-
section_id = id_for_section(section)
|
222
|
-
cache_key = "groupings-#{section_id}"
|
223
|
-
|
224
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:section, section_id, api_data)
|
225
|
-
return cache_read(cache_key)
|
226
|
-
end
|
227
|
-
|
228
|
-
data = perform_query("users.php?action=getPatrols§ionid=#{section_id}", api_data)
|
229
|
-
|
230
|
-
result = Array.new
|
231
|
-
data['patrols'].each do |item|
|
232
|
-
grouping = Osm::Grouping.from_api(item)
|
233
|
-
result.push grouping
|
234
|
-
self.user_can_access :grouping, grouping.id, api_data
|
235
|
-
end
|
236
|
-
cache_write(cache_key, result, :expires_in => @@default_cache_ttl*2)
|
237
|
-
|
238
|
-
return result
|
239
|
-
end
|
240
|
-
|
241
|
-
# Get the terms that the OSM user can access
|
242
|
-
# @!macro options_get
|
243
|
-
# @!macro options_api_data
|
244
|
-
# @return [Array<Osm::Term>]
|
245
|
-
def get_terms(options={}, api_data={})
|
246
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
247
|
-
cache_key = "terms-#{api_data[:userid] || @userid}"
|
248
|
-
|
249
|
-
if !options[:no_cache] && cache_exist?(cache_key)
|
250
|
-
return cache_read(cache_key)
|
251
|
-
end
|
252
|
-
|
253
|
-
data = perform_query('api.php?action=getTerms', api_data)
|
254
|
-
|
255
|
-
result = Array.new
|
256
|
-
data.each_key do |key|
|
257
|
-
data[key].each do |item|
|
258
|
-
term = Osm::Term.from_api(item)
|
259
|
-
result.push term
|
260
|
-
cache_write("term-#{term.id}", term, :expires_in => @@default_cache_ttl*2)
|
261
|
-
self.user_can_access :term, term.id, api_data
|
262
|
-
end
|
263
|
-
end
|
264
|
-
|
265
|
-
cache_write(cache_key, result, :expires_in => @@default_cache_ttl*2)
|
266
|
-
return result
|
267
|
-
end
|
268
|
-
|
269
|
-
# Get a term
|
270
|
-
# @param [Fixnum] term_id the id of the required term
|
271
|
-
# @!macro options_get
|
272
|
-
# @!macro options_api_data
|
273
|
-
# @return nil if an error occured or the user does not have access to that term
|
274
|
-
# @return [Osm::Term]
|
275
|
-
def get_term(term_id, options={}, api_data={})
|
276
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
277
|
-
cache_key = "term-#{term_id}"
|
278
|
-
|
279
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:term, term_id, api_data)
|
280
|
-
return cache_read(cache_key)
|
281
|
-
end
|
282
|
-
|
283
|
-
terms = get_terms(options)
|
284
|
-
return nil unless terms.is_a? Array
|
285
|
-
|
286
|
-
terms.each do |term|
|
287
|
-
return term if term.id == term_id
|
288
|
-
end
|
289
|
-
|
290
|
-
return nil
|
291
|
-
end
|
292
|
-
|
293
|
-
# Get the programme for a given term
|
294
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to get the programme for
|
295
|
-
# @param [Osm::term, Fixnum, nil] term the term (or its ID) to get the programme for, passing nil causes the current term to be used
|
296
|
-
# @!macro options_get
|
297
|
-
# @!macro options_api_data
|
298
|
-
# @return [Array<Osm::Evening>]
|
299
|
-
def get_programme(section, term, options={}, api_data={})
|
300
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
301
|
-
section_id = id_for_section(section)
|
302
|
-
term_id = id_for_term(term, section, api_data)
|
303
|
-
cache_key = "programme-#{section_id}-#{term_id}"
|
304
|
-
|
305
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:programme, section_id, api_data)
|
306
|
-
return cache_read(cache_key)
|
307
|
-
end
|
308
|
-
|
309
|
-
data = perform_query("programme.php?action=getProgramme§ionid=#{section_id}&termid=#{term_id}", api_data)
|
310
|
-
|
311
|
-
result = Array.new
|
312
|
-
data = {'items'=>[],'activities'=>{}} if data.is_a? Array
|
313
|
-
self.user_can_access(:programme, section_id, api_data) unless data.is_a? Array
|
314
|
-
items = data['items'] || []
|
315
|
-
activities = data['activities'] || {}
|
316
|
-
|
317
|
-
items.each do |item|
|
318
|
-
evening = Osm::Evening.from_api(item, activities[item['eveningid']])
|
319
|
-
result.push evening
|
320
|
-
evening.activities.each do |activity|
|
321
|
-
self.user_can_access :activity, activity.activity_id, api_data
|
322
|
-
end
|
323
|
-
end
|
324
|
-
|
325
|
-
cache_write(cache_key, result, :expires_in => @@default_cache_ttl)
|
326
|
-
return result
|
327
|
-
end
|
328
|
-
|
329
|
-
# Get the badge requirements met on a specific evening
|
330
|
-
# @param [Osm::Section] section the section to get the pbadge requirements for
|
331
|
-
# @param [Osm::Evening, DateTime, Date] evening the evening (or its date) to get the badge requirements for
|
332
|
-
# @!macro options_get
|
333
|
-
# @return [Array<Hash>] hashes ready to pass into the update_register method
|
334
|
-
def get_badge_requirements_for_evening(section, evening, options={})
|
335
|
-
evening = evening.meeting_date if evening.is_a?(Osm::Evening)
|
336
|
-
cache_key = "badge_requirements-#{section.id}-#{evening.strftime('%Y%m%d')}"
|
337
|
-
|
338
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:programme, section.id)
|
339
|
-
return cache_read(cache_key)
|
340
|
-
end
|
341
|
-
|
342
|
-
data = perform_query("users.php?action=getActivityRequirements&date=#{evening.strftime(Osm::OSM_DATE_FORMAT)}§ionid=#{section.id}§ion=#{section.type}")
|
343
|
-
|
344
|
-
cache_write(cache_key, data, :expires_in => @@default_cache_ttl)
|
345
|
-
return data
|
346
|
-
end
|
347
|
-
|
348
|
-
# Get activity details
|
349
|
-
# @param [Fixnum] activity_id the activity ID
|
350
|
-
# @param [Fixnum] version the version of the activity to retreive, if nil the latest version will be assumed
|
351
|
-
# @!macro options_get
|
352
|
-
# @!macro options_api_data
|
353
|
-
# @return [Osm::Activity]
|
354
|
-
def get_activity(activity_id, version=nil, options={}, api_data={})
|
355
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
356
|
-
cache_key = "activity-#{activity_id}-"
|
357
|
-
|
358
|
-
if !options[:no_cache] && cache_exist?("#{cache_key}-#{version}") && self.user_can_access?(:activity, activity_id, api_data)
|
359
|
-
return cache_read("#{cache_key}-#{version}")
|
360
|
-
end
|
361
|
-
|
362
|
-
data = nil
|
363
|
-
if version.nil?
|
364
|
-
data = perform_query("programme.php?action=getActivity&id=#{activity_id}", api_data)
|
365
|
-
else
|
366
|
-
data = perform_query("programme.php?action=getActivity&id=#{activity_id}&version=#{version}", api_data)
|
367
|
-
end
|
368
|
-
|
369
|
-
activity = Osm::Activity.from_api(data)
|
370
|
-
cache_write("#{cache_key}-#{nil}", activity, :expires_in => @@default_cache_ttl*2) if version.nil?
|
371
|
-
cache_write("#{cache_key}-#{activity.version}", activity, :expires_in => @@default_cache_ttl/2)
|
372
|
-
self.user_can_access :activity, activity.id, api_data
|
373
|
-
|
374
|
-
return activity
|
375
|
-
end
|
376
|
-
|
377
|
-
# Get members
|
378
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to get the members for
|
379
|
-
# @param [Osm::Term, Fixnum, nil] term the term (or its ID) to get the members for, passing nil causes the current term to be used
|
380
|
-
# @!macro options_get
|
381
|
-
# @!macro options_api_data
|
382
|
-
# @return [Array<Osm::Member>]
|
383
|
-
def get_members(section, term=nil, options={}, api_data={})
|
384
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
385
|
-
section_id = id_for_section(section)
|
386
|
-
term_id = id_for_term(term, section, api_data)
|
387
|
-
cache_key = "members-#{section_id}-#{term_id}"
|
388
|
-
|
389
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:member, section_id, api_data)
|
390
|
-
return cache_read(cache_key)
|
391
|
-
end
|
392
|
-
|
393
|
-
data = perform_query("users.php?action=getUserDetails§ionid=#{section_id}&termid=#{term_id}", api_data)
|
394
|
-
|
395
|
-
result = Array.new
|
396
|
-
data['items'].each do |item|
|
397
|
-
result.push Osm::Member.from_api(item, section_id)
|
398
|
-
end
|
399
|
-
self.user_can_access :member, section_id, api_data
|
400
|
-
cache_write(cache_key, result, :expires_in => @@default_cache_ttl)
|
401
|
-
|
402
|
-
return result
|
403
|
-
end
|
404
|
-
|
405
|
-
# Get API access details for a given section
|
406
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to get the details for
|
407
|
-
# @!macro options_get
|
408
|
-
# @!macro options_api_data
|
409
|
-
# @return [Array<Osm::ApiAccess>]
|
410
|
-
def get_api_access(section, options={}, api_data={})
|
411
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
412
|
-
section_id = id_for_section(section)
|
413
|
-
cache_key = "api_access-#{api_data['userid'] || @userid}-#{section_id}"
|
414
|
-
|
415
|
-
if !options[:no_cache] && cache_exist?(cache_key)
|
416
|
-
return cache_read(cache_key)
|
417
|
-
end
|
418
|
-
|
419
|
-
data = perform_query("users.php?action=getAPIAccess§ionid=#{section_id}", api_data)
|
420
|
-
|
421
|
-
result = Array.new
|
422
|
-
data['apis'].each do |item|
|
423
|
-
this_item = Osm::ApiAccess.from_api(item)
|
424
|
-
result.push this_item
|
425
|
-
self.user_can_access(:programme, section_id, api_data) if this_item.can_read?(:programme)
|
426
|
-
self.user_can_access(:member, section_id, api_data) if this_item.can_read?(:member)
|
427
|
-
self.user_can_access(:badge, section_id, api_data) if this_item.can_read?(:badge)
|
428
|
-
cache_write("#{cache_key}-#{this_item.id}", this_item, :expires_in => @@default_cache_ttl*2)
|
429
|
-
end
|
430
|
-
cache_write(cache_key, result, :expires_in => @@default_cache_ttl*2)
|
431
|
-
|
432
|
-
return result
|
433
|
-
end
|
434
|
-
|
435
|
-
# Get our API access details for a given section
|
436
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to get the details for
|
437
|
-
# @!macro options_get
|
438
|
-
# @!macro options_api_data
|
439
|
-
# @return [Osm::ApiAccess]
|
440
|
-
def get_our_api_access(section, options={}, api_data={})
|
441
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
442
|
-
section_id = id_for_section(section)
|
443
|
-
cache_key = "api_access-#{api_data['userid'] || @userid}-#{section_id}-#{Osm::Api.api_id}"
|
444
|
-
|
445
|
-
if !options[:no_cache] && cache_exist?(cache_key)
|
446
|
-
return cache_read(cache_key)
|
447
|
-
end
|
448
|
-
|
449
|
-
data = get_api_access(section_id, options)
|
450
|
-
found = nil
|
451
|
-
data.each do |item|
|
452
|
-
found = item if item.our_api?
|
453
|
-
end
|
454
|
-
|
455
|
-
return found
|
456
|
-
end
|
457
|
-
|
458
|
-
# Get events
|
459
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to get the events for
|
460
|
-
# @!macro options_get
|
461
|
-
# @option options [Boolean] :include_archived (optional) if true then archived activities will also be returned
|
462
|
-
# @!macro options_api_data
|
463
|
-
# @return [Array<Osm::Event>]
|
464
|
-
def get_events(section, options={}, api_data={})
|
465
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
466
|
-
section_id = id_for_section(section)
|
467
|
-
cache_key = "events-#{section_id}"
|
468
|
-
events = nil
|
469
|
-
|
470
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:events, section_id, api_data)
|
471
|
-
return cache_read(cache_key)
|
472
|
-
end
|
473
|
-
|
474
|
-
data = perform_query("events.php?action=getEvents§ionid=#{section_id}&showArchived=true", api_data)
|
475
|
-
|
476
|
-
events = Array.new
|
477
|
-
unless data['items'].nil?
|
478
|
-
data['items'].each do |item|
|
479
|
-
event = Osm::Event.from_api(item)
|
480
|
-
events.push event
|
481
|
-
cache_write("event-#{section_id}-#{event.id}", event, :expires_in => @@default_cache_ttl)
|
482
|
-
end
|
483
|
-
end
|
484
|
-
self.user_can_access :events, section_id, api_data
|
485
|
-
cache_write(cache_key, events, :expires_in => @@default_cache_ttl)
|
486
|
-
|
487
|
-
return events if options[:include_archived]
|
488
|
-
return events.reject do |event|
|
489
|
-
event.archived?
|
490
|
-
end
|
491
|
-
end
|
492
|
-
|
493
|
-
# Get event
|
494
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to get the events for
|
495
|
-
# @param [Fixnum] event_id the id of the event to get
|
496
|
-
# @!macro options_get
|
497
|
-
# @option options [Boolean] :include_archived (optional) if true then archived activities will also be returned
|
498
|
-
# @return [Osm::Event, nil] the event (or nil if it couldn't be found
|
499
|
-
def get_event(section, event_id, options={})
|
500
|
-
section_id = id_for_section(section)
|
501
|
-
cache_key = "event-#{section_id}-#{event_id}"
|
502
|
-
|
503
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:events, section_id)
|
504
|
-
return cache_read(cache_key)
|
505
|
-
end
|
506
|
-
|
507
|
-
events = get_events(section, options)
|
508
|
-
return nil unless events.is_a? Array
|
509
|
-
|
510
|
-
events.each do |event|
|
511
|
-
return event if event.id == event_id
|
512
|
-
end
|
513
|
-
|
514
|
-
return nil
|
515
|
-
end
|
516
|
-
|
517
|
-
# Get event fields
|
518
|
-
# @param [Osm::Event, Fixnum] event the event to get the fieldss for
|
519
|
-
# @param [Osm::Term, Fixnum, nil] term the term (or its ID) to get the members for, passing nil causes the current term to be used
|
520
|
-
# @!macro options_get
|
521
|
-
# @option options [Boolean] :include_archived (optional) if true then archived activities will also be returned
|
522
|
-
# @return [Hash] fields of data assigned to the event (keys is the id, value is the field names)
|
523
|
-
def get_event_fields(event, term=nil, options={})
|
524
|
-
term_id = id_for_term(term, event.section_id)
|
525
|
-
cache_key = "event-fields-#{event.section_id}-#{event.id}"
|
526
|
-
|
527
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:events, event.section_id)
|
528
|
-
return cache_read(cache_key)
|
529
|
-
end
|
530
|
-
|
531
|
-
data = perform_query("events.php?action=getEvent§ionid=#{event.section_id}&eventid=#{event.id}")
|
532
|
-
|
533
|
-
fields = {}
|
534
|
-
ActiveSupport::JSON.decode(data['config']).each do |field|
|
535
|
-
fields[field['id']] = field['name']
|
536
|
-
end
|
537
|
-
|
538
|
-
self.user_can_access :events, event.section_id
|
539
|
-
cache_write(cache_key, fields, :expires_in => @@default_cache_ttl)
|
540
|
-
return fields
|
541
|
-
end
|
542
|
-
|
543
|
-
# Get event attendance
|
544
|
-
# @param [Osm::Event] event the event to get the fieldss for
|
545
|
-
# @param [Osm::Term, Fixnum, nil] term the term (or its ID) to get the members for, passing nil causes the current term to be used
|
546
|
-
# @!macro options_get
|
547
|
-
# @option options [Boolean] :include_archived (optional) if true then archived activities will also be returned
|
548
|
-
# @return [Hash] fields of data assigned to the event (keys is the id, value is the field names)
|
549
|
-
def get_event_attendance(event, term=nil, options={})
|
550
|
-
term_id = id_for_term(term, event.section_id)
|
551
|
-
cache_key = "event-attendance-#{event.section_id}-#{event.id}"
|
552
|
-
|
553
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:events, event.section_id)
|
554
|
-
return cache_read(cache_key)
|
555
|
-
end
|
556
|
-
|
557
|
-
data = perform_query("events.php?action=getEventAttendance&eventid=#{event.id}§ionid=#{event.section_id}&termid=#{term_id}")
|
558
|
-
data = data['items']
|
559
|
-
|
560
|
-
to_return = []
|
561
|
-
data.each_with_index do |item, index|
|
562
|
-
to_return.push Osm::EventAttendance.from_api(item, index)
|
563
|
-
end
|
564
|
-
self.user_can_access :events, event.section_id
|
565
|
-
cache_write(cache_key, to_return, :expires_in => @@default_cache_ttl/2)
|
566
|
-
return to_return
|
567
|
-
end
|
568
|
-
|
569
|
-
# Get due badges
|
570
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to get the due badges for
|
571
|
-
# @param [Osm::Term, Fixnum, nil] term the term (or its ID) to get the due badges for, passing nil causes the current term to be used
|
572
|
-
# @!macro options_get
|
573
|
-
# @!macro options_api_data
|
574
|
-
# @return [Osm::DueBadges]
|
575
|
-
def get_due_badges(section, term=nil, options={}, api_data={})
|
576
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
577
|
-
section_id = id_for_section(section)
|
578
|
-
section_type = type_for_section(section, api_data)
|
579
|
-
term_id = id_for_term(term, section, api_data)
|
580
|
-
cache_key = "due_badges-#{section_id}-#{term_id}"
|
581
|
-
|
582
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:badge, section_id, api_data)
|
583
|
-
return cache_read(cache_key)
|
584
|
-
end
|
585
|
-
|
586
|
-
data = perform_query("challenges.php?action=outstandingBadges§ion=#{section_type}§ionid=#{section_id}&termid=#{term_id}", api_data)
|
587
|
-
|
588
|
-
data = Osm::DueBadges.from_api(data)
|
589
|
-
self.user_can_access :badge, section_id, api_data
|
590
|
-
cache_write(cache_key, data, :expires_in => @@default_cache_ttl*2)
|
591
|
-
|
592
|
-
return data
|
593
|
-
end
|
594
|
-
|
595
|
-
# Get register structure
|
596
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to get the structure for
|
597
|
-
# @param [Osm::Term, Fixnum, nil] section the term (or its ID) to get the structure for, passing nil causes the current term to be used
|
598
|
-
# @!macro options_get
|
599
|
-
# @!macro options_api_data
|
600
|
-
# @return [Array<Osm::RegisterField>] representing the fields of the register
|
601
|
-
def get_register_structure(section, term=nil, options={}, api_data={})
|
602
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
603
|
-
section_id = id_for_section(section)
|
604
|
-
term_id = id_for_term(term, section, api_data)
|
605
|
-
cache_key = "register_structure-#{section_id}-#{term_id}"
|
606
|
-
|
607
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:register, section_id, api_data)
|
608
|
-
return cache_read(cache_key)
|
609
|
-
end
|
610
|
-
|
611
|
-
data = perform_query("users.php?action=registerStructure§ionid=#{section_id}&termid=#{term_id}", api_data)
|
612
|
-
|
613
|
-
structure = []
|
614
|
-
data.each do |item|
|
615
|
-
item['rows'].each do |row|
|
616
|
-
structure.push Osm::RegisterField.from_api(row)
|
617
|
-
end
|
618
|
-
end
|
619
|
-
self.user_can_access :register, section_id, api_data
|
620
|
-
cache_write(cache_key, structure, :expires_in => @@default_cache_ttl/2)
|
621
|
-
|
622
|
-
return structure
|
623
|
-
end
|
624
|
-
|
625
|
-
# Get register data
|
626
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to get the register for
|
627
|
-
# @param [Osm::Term, Fixnum, nil] section the term (or its ID) to get the register for, passing nil causes the current term to be used
|
628
|
-
# @!macro options_get
|
629
|
-
# @!macro options_api_data
|
630
|
-
# @return [Array<RegisterData>] representing the attendance of each member
|
631
|
-
def get_register_data(section, term=nil, options={}, api_data={})
|
632
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
633
|
-
section_id = id_for_section(section)
|
634
|
-
term_id = id_for_term(term, section, api_data)
|
635
|
-
cache_key = "register-#{section_id}-#{term_id}"
|
636
|
-
|
637
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:register, section_id, api_data)
|
638
|
-
return cache_read(cache_key)
|
639
|
-
end
|
640
|
-
|
641
|
-
data = perform_query("users.php?action=register§ionid=#{section_id}&termid=#{term_id}", api_data)
|
642
|
-
|
643
|
-
data = data['items']
|
644
|
-
to_return = []
|
645
|
-
data.each do |item|
|
646
|
-
to_return.push Osm::RegisterData.from_api(item)
|
647
|
-
end
|
648
|
-
self.user_can_access :register, section_id, api_data
|
649
|
-
cache_write(cache_key, to_return, :expires_in => @@default_cache_ttl/2)
|
650
|
-
return to_return
|
651
|
-
end
|
652
|
-
|
653
|
-
# Get flexirecord structure
|
654
|
-
# @param [Osm::Section, Fixnum] section the section (or its ID) to get the structure for
|
655
|
-
# @param [Fixnum] the id of the Flexi Record
|
656
|
-
# @!macro options_get
|
657
|
-
# @!macro options_api_data
|
658
|
-
# @return [Array<Osm::FlexiRecordField>] representing the fields of the flexi record
|
659
|
-
def get_flexi_record_fields(section, id, options={}, api_data={})
|
660
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
661
|
-
section_id = id_for_section(section)
|
662
|
-
cache_key = "flexi_record_structure-#{section_id}-#{id}"
|
663
|
-
|
664
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:flexi, section_id, api_data)
|
665
|
-
return cache_read(cache_key)
|
666
|
-
end
|
667
|
-
|
668
|
-
data = perform_query("extras.php?action=getExtra§ionid=#{section_id}&extraid=#{id}", api_data)
|
669
|
-
|
670
|
-
structure = []
|
671
|
-
data['structure'].each do |item|
|
672
|
-
item['rows'].each do |row|
|
673
|
-
structure.push Osm::FlexiRecordField.from_api(row)
|
674
|
-
end
|
675
|
-
end
|
676
|
-
self.user_can_access :flexi, section_id, api_data
|
677
|
-
cache_write(cache_key, structure, :expires_in => @@default_cache_ttl/2)
|
678
|
-
|
679
|
-
return structure
|
680
|
-
end
|
681
|
-
|
682
|
-
# Get flexi record data
|
683
|
-
# @param [Osm:Section, Fixnum] section the section (or its ID) to get the register for
|
684
|
-
# @param [Fixnum] the id of the Flexi Record
|
685
|
-
# @param [Osm:Term, Fixnum, nil] section the term (or its ID) to get the register for, passing nil causes the current term to be used
|
686
|
-
# @!macro options_get
|
687
|
-
# @!macro options_api_data
|
688
|
-
# @return [Array<FlexiRecordData>]
|
689
|
-
def get_flexi_record_data(section, id, term=nil, options={}, api_data={})
|
690
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
691
|
-
section_id = id_for_section(section)
|
692
|
-
section_type = type_for_section(section, api_data)
|
693
|
-
term_id = id_for_term(term, section, api_data)
|
694
|
-
cache_key = "flexi_record_data-#{section_id}-#{term_id}-#{id}"
|
695
|
-
|
696
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:flexi, section_id, api_data)
|
697
|
-
return cache_read(cache_key)
|
698
|
-
end
|
699
|
-
|
700
|
-
data = perform_query("extras.php?action=getExtraRecords§ionid=#{section_id}&extraid=#{id}&termid=#{term_id}§ion=#{section_type}", api_data)
|
701
|
-
|
702
|
-
to_return = []
|
703
|
-
data['items'].each do |item|
|
704
|
-
to_return.push Osm::FlexiRecordData.from_api(item)
|
705
|
-
end
|
706
|
-
self.user_can_access :flexi, section_id, api_data
|
707
|
-
cache_write(cache_key, to_return, :expires_in => @@default_cache_ttl/2)
|
708
|
-
return to_return
|
50
|
+
nil
|
709
51
|
end
|
710
52
|
|
711
|
-
#
|
712
|
-
# @param [
|
713
|
-
# @param [
|
714
|
-
#
|
715
|
-
# @return
|
716
|
-
def
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
cache_key = "badge_stock-#{section_id}-#{term_id}"
|
721
|
-
|
722
|
-
if !options[:no_cache] && cache_exist?(cache_key) && self.user_can_access?(:badge, section_id)
|
723
|
-
return cache_read(cache_key)
|
724
|
-
end
|
725
|
-
|
726
|
-
data = perform_query("challenges.php?action=getInitialBadges&type=core§ionid=#{section_id}§ion=#{section_type}&termid=#{term_id}")
|
727
|
-
data = (data['stock'] || {}).select{ |k,v| !k.eql?('sectionid') }.
|
728
|
-
inject({}){ |new_hash,(badge, level)| new_hash[badge] = level.to_i; new_hash }
|
53
|
+
# Initialize a new API connection
|
54
|
+
# @param [String] user_id osm userid of the user to act as (get this by using the authorize method)
|
55
|
+
# @param [String] secret osm secret of the user to act as (get this by using the authorize method)
|
56
|
+
# @param [Symbol] site wether to use OSM (:osm) or OGM (:ogm), defaults to the value set for the class
|
57
|
+
# @return nil
|
58
|
+
def initialize(user_id, secret, site=@@site)
|
59
|
+
raise ArgumentError, 'You must pass a secret (get this by using the authorize method)' if secret.nil?
|
60
|
+
raise ArgumentError, 'You must pass a user_id (get this by using the authorize method)' if user_id.nil?
|
61
|
+
raise ArgumentError, 'site is invalid, if passed it should be either :osm or :ogm, if not passed then you forgot to run Api.configure' unless [:osm, :ogm].include?(site)
|
729
62
|
|
730
|
-
|
731
|
-
|
732
|
-
|
63
|
+
@site = site
|
64
|
+
set_user(user_id, secret)
|
65
|
+
nil
|
733
66
|
end
|
734
67
|
|
735
68
|
|
736
|
-
#
|
737
|
-
# @
|
738
|
-
|
739
|
-
|
740
|
-
# @return [Boolean] if the operation suceeded or not
|
741
|
-
def create_evening(section, meeting_date, api_data={})
|
742
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
743
|
-
section_id = id_for_section(section)
|
744
|
-
evening_api_data = {
|
745
|
-
'meetingdate' => meeting_date.strftime(Osm::OSM_DATE_FORMAT),
|
746
|
-
'sectionid' => section_id,
|
747
|
-
'activityid' => -1
|
748
|
-
}
|
749
|
-
|
750
|
-
data = perform_query("programme.php?action=addActivityToProgramme", api_data.merge(evening_api_data))
|
751
|
-
|
752
|
-
# The cached programmes for the section will be out of date - remove them
|
753
|
-
get_terms(api_data).each do |term|
|
754
|
-
cache_delete("programme-#{term.section_id}-#{term.id}") if term.section_id == section_id
|
755
|
-
end
|
756
|
-
|
757
|
-
return data.is_a?(Hash) && (data['result'] == 0)
|
69
|
+
# Get the API name
|
70
|
+
# @return [String]
|
71
|
+
def api_name
|
72
|
+
@@api_details[@site][:name]
|
758
73
|
end
|
759
74
|
|
760
|
-
#
|
761
|
-
# @
|
762
|
-
|
763
|
-
|
764
|
-
raise ArgumentIsInvalid, 'event is invalid' unless event.valid?
|
765
|
-
|
766
|
-
data = perform_query("events.php?action=addEvent§ionid=#{event.section_id}", {
|
767
|
-
'name' => event.name,
|
768
|
-
'location' => event.location,
|
769
|
-
'startdate' => event.start.strftime(Osm::OSM_DATE_FORMAT),
|
770
|
-
'enddate' => event.finish.strftime(Osm::OSM_DATE_FORMAT),
|
771
|
-
'cost' => event.cost,
|
772
|
-
'notes' => event.notes,
|
773
|
-
'starttime' => event.start.strftime(Osm::OSM_TIME_FORMAT),
|
774
|
-
'endtime' => event.finish.strftime(Osm::OSM_TIME_FORMAT),
|
775
|
-
})
|
776
|
-
|
777
|
-
# The cached events for the section will be out of date - remove them
|
778
|
-
get_events(event.section_id).each do |item|
|
779
|
-
cache_delete("event-#{item.section_id}-#{item.id}")
|
780
|
-
end
|
781
|
-
cache_delete("events-#{event.section_id}")
|
782
|
-
|
783
|
-
return data.is_a?(Hash) ? data['id'] : nil
|
75
|
+
# Get the API ID
|
76
|
+
# @return [String]
|
77
|
+
def api_id
|
78
|
+
@@api_details[@site][:id]
|
784
79
|
end
|
785
|
-
|
786
|
-
|
787
|
-
# @param [Osm::Event] event the event to update in OSM
|
788
|
-
# @return [Boolean] wether the update succedded
|
789
|
-
def update_event(event)
|
790
|
-
raise ArgumentIsInvalid, 'event is invalid' unless event.valid?
|
791
|
-
|
792
|
-
data = perform_query("events.php?action=addEvent§ionid=#{event.section_id}", {
|
793
|
-
'eventid' => event.id,
|
794
|
-
'name' => event.name,
|
795
|
-
'location' => event.location,
|
796
|
-
'startdate' => event.start? ? event.start.strftime(Osm::OSM_DATE_FORMAT) : '',
|
797
|
-
'enddate' => event.finish? ? event.finish.strftime(Osm::OSM_DATE_FORMAT) : '',
|
798
|
-
'cost' => event.cost,
|
799
|
-
'notes' => event.notes,
|
800
|
-
'starttime' => event.start? ? event.start.strftime(Osm::OSM_TIME_FORMAT) : '',
|
801
|
-
'endtime' => event.finish? ? event.finish.strftime(Osm::OSM_TIME_FORMAT) : '',
|
802
|
-
})
|
803
|
-
|
804
|
-
# The cached events for the section will be out of date - remove them
|
805
|
-
get_events(event.section_id).each do |item|
|
806
|
-
cache_delete("event-#{item.section_id}-#{item.id}")
|
807
|
-
end
|
808
|
-
cache_delete("events-#{event.section_id}")
|
809
|
-
|
810
|
-
return data.is_a?(Hash) && (data['id'].to_i == event.id)
|
80
|
+
def to_i
|
81
|
+
api_id
|
811
82
|
end
|
812
83
|
|
813
|
-
# Delete an event from OSM
|
814
|
-
# @param [Osm::Event] event the event to delete from OSM
|
815
|
-
# @return [Boolean] wether the delete succedded
|
816
|
-
def delete_event(event)
|
817
|
-
raise ArgumentIsInvalid, 'event is invalid' unless event.valid?
|
818
|
-
|
819
|
-
data = perform_query("events.php?action=deleteEvent§ionid=#{event.section_id}&eventid=#{event.id}", {})
|
820
|
-
|
821
|
-
# The cached events for the section will be out of date - remove them
|
822
|
-
cache_delete("event-#{event.section_id}-#{event.id}")
|
823
|
-
cache_delete("events-#{event.section_id}")
|
824
84
|
|
825
|
-
|
85
|
+
# Get the site this Api currently uses
|
86
|
+
# @return [Symbol] :osm or :ogm
|
87
|
+
def site
|
88
|
+
@site
|
826
89
|
end
|
827
90
|
|
828
|
-
# Add a field to an Event in OSM
|
829
|
-
# @param [Osm::Event] event the event to update in OSM
|
830
|
-
# @param [String] field_label the label for the field to add
|
831
|
-
# @return [Boolean] wether the update succedded
|
832
|
-
def add_event_field(event, field_label)
|
833
|
-
raise ArgumentIsInvalid, 'event is invalid' unless event.valid?
|
834
|
-
raise ArgumentIsInvalid, 'field_label is invalid' if field_label.blank?
|
835
|
-
|
836
|
-
data = perform_query("events.php?action=addColumn§ionid=#{event.section_id}&eventid=#{event.id}", {
|
837
|
-
'columnName' => field_label
|
838
|
-
})
|
839
91
|
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
return data.is_a?(Hash) && (data['eventid'].to_i == event.id)
|
92
|
+
# Get the current user_id
|
93
|
+
# @return [String]
|
94
|
+
def user_id
|
95
|
+
@user_id
|
845
96
|
end
|
846
97
|
|
847
|
-
# Create a term in OSM
|
848
|
-
# @param [Hash] options - the configuration of the new term
|
849
|
-
# @option options [Osm::Section, Fixnum] :section (required) section or section_id to add the term to
|
850
|
-
# @option options [String] :name (required) the name for the term
|
851
|
-
# @option options [Date] :start (required) the date for the start of term
|
852
|
-
# @option options [Date] :finish (required) the date for the finish of term
|
853
|
-
# @return [Boolean] if the operation suceeded or not
|
854
|
-
def create_term(options={})
|
855
|
-
raise ArgumentError, ":section can't be nil" if options[:section].nil?
|
856
|
-
raise ArgumentError, ":name can't be nil" if options[:name].nil?
|
857
|
-
raise ArgumentError, ":start can't be nil" if options[:start].nil?
|
858
|
-
raise ArgumentError, ":finish can't be nil" if options[:finish].nil?
|
859
98
|
|
860
|
-
|
99
|
+
# Get the userid and secret to be able to act as a certain user on the OSM/OGM system
|
100
|
+
# @param [Symbol] site The site to use either :osm or :ogm (defaults to whatever was set in the configure method)
|
101
|
+
# @param [String] email the login email address of the user on OSM
|
102
|
+
# @param [String] password the login password of the user on OSM
|
103
|
+
# @return [Hash] a hash containing the following keys:
|
104
|
+
# * :user_id - the userid to use in future requests
|
105
|
+
# * :secret - the secret to use in future requests
|
106
|
+
def self.authorize(site=@@site, email, password)
|
861
107
|
api_data = {
|
862
|
-
'
|
863
|
-
'
|
864
|
-
|
865
|
-
|
108
|
+
'email' => email,
|
109
|
+
'password' => password,
|
110
|
+
}
|
111
|
+
data = perform_query(site, 'users.php?action=authorise', api_data)
|
112
|
+
return {
|
113
|
+
:user_id => data['userid'],
|
114
|
+
:secret => data['secret'],
|
866
115
|
}
|
867
|
-
|
868
|
-
data = perform_query("users.php?action=addTerm§ionid=#{section_id}", api_data)
|
869
|
-
|
870
|
-
# The cached terms for the section will be out of date - remove them
|
871
|
-
get_terms.each do |term|
|
872
|
-
cache_delete("term-#{term.id}") if term.section_id == section_id
|
873
|
-
end
|
874
|
-
cache_delete("terms-#{@userid}")
|
875
|
-
|
876
|
-
return data.is_a?(Hash) && data['terms'].is_a?(Hash)
|
877
|
-
end
|
878
|
-
|
879
|
-
|
880
|
-
# Update an evening in OSM
|
881
|
-
# @param [Osm::Evening] evening the evening to update
|
882
|
-
# @!macro options_api_data
|
883
|
-
# @return [Boolean] if the operation suceeded or not
|
884
|
-
def update_evening(evening, api_data={})
|
885
|
-
warn "[DEPRECATION OF OPTION] use of the api_data option is deprecated." unless api_data == {}
|
886
|
-
raise ArgumentIsInvalid, 'evening is invalid' unless evening.valid?
|
887
|
-
response = perform_query("programme.php?action=editEvening", api_data.merge(evening.to_api))
|
888
|
-
|
889
|
-
# The cached programmes for the section will be out of date - remove them
|
890
|
-
get_terms(api_data).each do |term|
|
891
|
-
cache_delete("programme-#{term.section_id}-#{term.id}") if term.section_id == evening.section_id
|
892
|
-
end
|
893
|
-
|
894
|
-
return response.is_a?(Hash) && (response['result'] == 0)
|
895
|
-
end
|
896
|
-
|
897
|
-
|
898
|
-
# Update register for an evening in OSM
|
899
|
-
# @param [Hash] data
|
900
|
-
# @option data [Osm::Section] :section the section to update the register for
|
901
|
-
# @option data [Osm::Term, Fixnum, nil] :term the term (or its ID) to get the register for, passing nil causes the current term to be used
|
902
|
-
# @option data [Osm::Evening, DateTime, Date] :evening the evening to update the register on
|
903
|
-
# @option data [String] :attendance what to mark the attendance as, one of "Yes", "No" or "Absent"
|
904
|
-
# @option data [Fixnum, Array<Fixnum>, Osm::Member, Array<Osm::Member>] :members the members (or their ids) to update
|
905
|
-
# @option data [Array<Hash>] :completed_badge_requirements (optional) the badge requirements to mark as completed, selected from the Hash returned by the get_badge_requirements_for_evening method
|
906
|
-
# @return [Boolean] wether the update succedded
|
907
|
-
def update_register(data={})
|
908
|
-
raise ArgumentIsInvalid, ':attendance is invalid' unless ['Yes', 'No', 'Absent'].include?(data[:attendance])
|
909
|
-
raise ArgumentIsInvalid, ':section is missing' if data[:section].nil?
|
910
|
-
raise ArgumentIsInvalid, ':evening is missing' if data[:evening].nil?
|
911
|
-
raise ArgumentIsInvalid, ':members is missing' if data[:members].nil?
|
912
|
-
|
913
|
-
term_id = id_for_term(data[:term], data[:section])
|
914
|
-
|
915
|
-
data[:members] = [data[:members]] unless data[:members].is_a?(Array) # Make sure it's an Array
|
916
|
-
data[:members] = data[:members].map{ |member| (member.is_a?(Fixnum) ? member : member.id).to_s } # Make sure it's an Array of Strings
|
917
|
-
|
918
|
-
response = perform_query("users.php?action=registerUpdate§ionid=#{data[:section].id}&termid=#{term_id}", {
|
919
|
-
'scouts' => data[:members].inspect,
|
920
|
-
'selectedDate' => data[:evening].strftime(Osm::OSM_DATE_FORMAT),
|
921
|
-
'present' => data[:attendance],
|
922
|
-
'section' => data[:section].type,
|
923
|
-
'sectionid' => data[:section].id,
|
924
|
-
'completedBadges' => (data[:completed_badge_requirements] || []).to_json
|
925
|
-
})
|
926
|
-
|
927
|
-
# The cached attendance will be out of date - remove them
|
928
|
-
cache_delete("register-#{data[:section].id}-#{term_id}")
|
929
|
-
|
930
|
-
return response.is_a?(Array)
|
931
|
-
end
|
932
|
-
|
933
|
-
# Update a term in OSM
|
934
|
-
# @param [Osm::Term] term the term to update
|
935
|
-
# @return [Boolean] if the operation suceeded or not
|
936
|
-
def update_term(term)
|
937
|
-
raise ArgumentIsInvalid, 'term is invalid' unless term.valid?
|
938
|
-
|
939
|
-
data = perform_query("users.php?action=addTerm§ionid=#{term.section_id}", term.to_api)
|
940
|
-
|
941
|
-
# The cached terms for the section will be out of date - remove them
|
942
|
-
cache_delete("term-#{term.id}")
|
943
|
-
cache_delete("terms-#{@userid}")
|
944
|
-
|
945
|
-
return data.is_a?(Hash) && data['terms'].is_a?(Hash)
|
946
|
-
end
|
947
|
-
|
948
|
-
# Update event attendance
|
949
|
-
# @param [Osm::Event] event the event to update the attendance of
|
950
|
-
# @param [Osm::EventAttendance] event_attendance the attendance record to update
|
951
|
-
# @param [String] field_id the id of the field to update (must be 'attending' or /\Af_\d+\Z/)
|
952
|
-
# @return [Boolean] if the operation suceeded or not
|
953
|
-
def update_event_attendance(event, event_attendance, field_id)
|
954
|
-
raise ArgumentIsInvalid, 'event is invalid' unless event.valid?
|
955
|
-
raise ArgumentIsInvalid, 'event_attendance is invalid' unless event_attendance.valid?
|
956
|
-
raise ArgumentIsInvalid, 'field_id is invalid' unless field_id.match(/\Af_\d+\Z/) || field_id.eql?('attending')
|
957
|
-
|
958
|
-
data = perform_query("events.php?action=updateScout", {
|
959
|
-
'scoutid' => event_attendance.member_id,
|
960
|
-
'column' => field_id,
|
961
|
-
'value' => !field_id.eql?('attending') ? event_attendance.fields[field_id] : (event_attendance.fields['attending'] ? 'Yes' : 'No'),
|
962
|
-
'sectionid' => event.section_id,
|
963
|
-
'row' => event_attendance.row,
|
964
|
-
'eventid' => event.id,
|
965
|
-
})
|
966
|
-
|
967
|
-
# The cached event attedance will be out of date
|
968
|
-
cache_delete("event-attendance-#{event.section_id}-#{event.id}")
|
969
|
-
|
970
|
-
return data.is_a?(Hash)
|
971
116
|
end
|
972
|
-
|
973
|
-
|
974
117
|
|
975
|
-
protected
|
976
|
-
# Set access permission for the current user on a resource stored in the cache
|
977
|
-
# @param [Symbol] resource_type a symbol representing the resource type (:section, :grouping, :term, :activity, :programme, :member, :badge, :register)
|
978
|
-
# @param [Fixnum] resource_id the id of the resource being checked
|
979
|
-
# @param [Hash] api_data the data hash used in accessing the api
|
980
|
-
# @param [Boolean] permission wether the user can access the resource
|
981
|
-
# @return [Boolean] the permission which was set
|
982
|
-
def user_can_access(resource_type, resource_id, api_data={}, permission=true)
|
983
|
-
user = (api_data['userid'] || @userid).to_i
|
984
|
-
resource_id = resource_id.to_i
|
985
|
-
resource_type = resource_type.to_sym
|
986
118
|
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
119
|
+
# Set the OSM user to make future requests as
|
120
|
+
# @param [String] user_id the OSM userid to use (get this using the authorize method)
|
121
|
+
# @param [String] secret the OSM secret to use (get this using the authorize method)
|
122
|
+
# @return [Osm::Api] self
|
123
|
+
def set_user(user_id, secret)
|
124
|
+
@user_id = user_id
|
125
|
+
@user_secret = secret
|
126
|
+
return self
|
991
127
|
end
|
992
128
|
|
993
|
-
# Get access permission for the current user on a resource stored in the cache
|
994
|
-
# @param [Symbol] resource_type a symbol representing the resource type (:section, :grouping, :term, :activity, :programme, :member, :badge, :register)
|
995
|
-
# @param [Fixnum] resource_id the id of the resource being checked
|
996
|
-
# @param [Hash] api_data the data hash used in accessing the api
|
997
|
-
# @return nil if the combination of user and resource has not been set
|
998
|
-
# @return [Boolean] if the user can access the resource
|
999
|
-
def user_can_access?(resource_type, resource_id, api_data={})
|
1000
|
-
user = (api_data['userid'] || @userid).to_i
|
1001
|
-
resource_id = resource_id.to_i
|
1002
|
-
resource_type = resource_type.to_sym
|
1003
129
|
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
130
|
+
# Make a query to the OSM/OGM API
|
131
|
+
# @param [String] url the script on the remote server to invoke
|
132
|
+
# @param [Hash] api_data a hash containing the values to be sent to the server in the body of the request
|
133
|
+
# @return [Hash, Array, String] the parsed JSON returned by OSM
|
134
|
+
def perform_query(url, api_data={})
|
135
|
+
self.class.perform_query(@site, url, api_data.merge({
|
136
|
+
'userid' => @user_id,
|
137
|
+
'secret' => @user_secret,
|
138
|
+
}))
|
1007
139
|
end
|
1008
140
|
|
1009
|
-
|
1010
141
|
private
|
1011
|
-
# Make
|
142
|
+
# Make a query to the OSM/OGM API
|
143
|
+
# @param [Symbol] site The site to use either :osm or :ogm
|
1012
144
|
# @param [String] url the script on the remote server to invoke
|
1013
|
-
# @param [Hash] api_data a hash containing the values to be sent to the server
|
1014
|
-
# @option api_data [String] 'userid' (optional) the OSM userid to make the request as
|
1015
|
-
# @option api_data [String] 'secret' (optional) the OSM secret belonging to the above user
|
145
|
+
# @param [Hash] api_data a hash containing the values to be sent to the server in the body of the request
|
1016
146
|
# @return [Hash, Array, String] the parsed JSON returned by OSM
|
1017
|
-
def perform_query(url, api_data={})
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
1022
|
-
|
1023
|
-
|
1024
|
-
api_data['secret'] = @secret
|
1025
|
-
end
|
1026
|
-
end
|
147
|
+
def self.perform_query(site, url, api_data={})
|
148
|
+
raise ArgumentError, 'site is invalid, this should be set to either :osm or :ogm' unless [:osm, :ogm].include?(site)
|
149
|
+
|
150
|
+
data = api_data.merge({
|
151
|
+
'apiid' => @@api_details[site][:id],
|
152
|
+
'token' => @@api_details[site][:token],
|
153
|
+
})
|
1027
154
|
|
1028
155
|
if @@debug
|
1029
|
-
puts "Making
|
156
|
+
puts "Making :#{site} API request to #{url}"
|
1030
157
|
hide_values_for = ['secret', 'token']
|
1031
158
|
api_data_as_string = api_data.sort.map{ |key, value| "#{key} => #{hide_values_for.include?(key) ? 'PRESENT' : value.inspect}" }.join(', ')
|
1032
159
|
puts "{#{api_data_as_string}}"
|
1033
160
|
end
|
1034
161
|
|
1035
162
|
begin
|
1036
|
-
result = HTTParty.post("#{
|
163
|
+
result = HTTParty.post("#{BASE_URLS[site]}/#{url}", {:body => data})
|
1037
164
|
rescue SocketError, TimeoutError, OpenSSL::SSL::SSLError
|
1038
|
-
raise ConnectionError, 'A problem occured on the internet.'
|
165
|
+
raise Osm::ConnectionError, 'A problem occured on the internet.'
|
1039
166
|
end
|
1040
|
-
raise ConnectionError, "HTTP Status code was #{result.response.code}" if !result.response.code.eql?('200')
|
167
|
+
raise Osm::ConnectionError, "HTTP Status code was #{result.response.code}" if !result.response.code.eql?('200')
|
1041
168
|
|
1042
169
|
if @@debug
|
1043
|
-
puts "Result from
|
170
|
+
puts "Result from :#{site} request to #{url}"
|
1044
171
|
puts result.response.body
|
1045
172
|
end
|
1046
173
|
|
1047
|
-
raise Error, result.response.body unless looks_like_json?(result.response.body)
|
174
|
+
raise Osm::Error, result.response.body unless looks_like_json?(result.response.body)
|
1048
175
|
decoded = ActiveSupport::JSON.decode(result.response.body)
|
1049
176
|
osm_error = get_osm_error(decoded)
|
1050
|
-
raise Error, osm_error if osm_error
|
177
|
+
raise Osm::Error, osm_error if osm_error
|
1051
178
|
return decoded
|
1052
179
|
end
|
1053
180
|
|
1054
181
|
# Check if text looks like it's JSON
|
1055
182
|
# @param [String] text what to look at
|
1056
183
|
# @return [Boolean]
|
1057
|
-
def looks_like_json?(text)
|
184
|
+
def self.looks_like_json?(text)
|
1058
185
|
(['[', '{'].include?(text[0]))
|
1059
186
|
end
|
1060
187
|
|
@@ -1062,56 +189,13 @@ module Osm
|
|
1062
189
|
# @param data what OSM gave us
|
1063
190
|
# @return false if no error message was found
|
1064
191
|
# @return [String] the error message
|
1065
|
-
def get_osm_error(data)
|
192
|
+
def self.get_osm_error(data)
|
1066
193
|
return false unless data.is_a?(Hash)
|
1067
194
|
to_return = data['error'] || data['err'] || false
|
1068
195
|
to_return = false if to_return.blank?
|
1069
196
|
return to_return
|
1070
197
|
end
|
1071
198
|
|
1072
|
-
# Wrap cache calls
|
1073
|
-
def cache_read(key)
|
1074
|
-
return @@cache.nil? ? nil : @@cache.read("#{@@cache_prepend_to_key}-#{key}")
|
1075
|
-
end
|
1076
|
-
def cache_write(key, data, options={})
|
1077
|
-
return @@cache.nil? ? false : @@cache.write("#{@@cache_prepend_to_key}-#{key}", data, options)
|
1078
|
-
end
|
1079
|
-
def cache_exist?(key)
|
1080
|
-
return @@cache.nil? ? false : @@cache.exist?("#{@@cache_prepend_to_key}-#{key}")
|
1081
|
-
end
|
1082
|
-
def cache_delete(key)
|
1083
|
-
return @@cache.nil? ? true : @@cache.delete("#{@@cache_prepend_to_key}-#{key}")
|
1084
|
-
end
|
1085
|
-
|
1086
|
-
# Get the ID from an object or fixnum
|
1087
|
-
# @param cl the Class being used (e.g. Osm::Section)
|
1088
|
-
# @param value the value to get the ID from
|
1089
|
-
# @param [String] error_name the name of the class to use in error messages
|
1090
|
-
# @param [String, Symbol] id_method the method to call on cl to get the ID
|
1091
|
-
# @return [Fixnum] the ID
|
1092
|
-
def id_for(cl, value, error_name, id_method=:id)
|
1093
|
-
if value.is_a?(cl)
|
1094
|
-
value = value.send(id_method)
|
1095
|
-
else
|
1096
|
-
raise ArgumentError, "Invalid type for #{error_name}" unless value.is_a?(Fixnum)
|
1097
|
-
end
|
1098
|
-
|
1099
|
-
raise ArgumentError, "Invalid #{error_name} ID" unless value > 0
|
1100
|
-
return value
|
1101
|
-
end
|
1102
|
-
|
1103
|
-
def id_for_section(section)
|
1104
|
-
id_for(Osm::Section, section, 'section')
|
1105
|
-
end
|
1106
|
-
|
1107
|
-
def type_for_section(section, api_data={})
|
1108
|
-
(section.is_a?(Osm::Section) ? section : get_section(section, api_data)).type.to_s
|
1109
|
-
end
|
1110
|
-
|
1111
|
-
def id_for_term(term, section, api_data={})
|
1112
|
-
return term.nil? ? Osm::find_current_term_id(self, id_for_section(section), api_data) : id_for(Osm::Term, term, 'term')
|
1113
|
-
end
|
1114
|
-
|
1115
199
|
end # Class Api
|
1116
200
|
|
1117
201
|
end # Module
|