osm 0.0.17 → 0.0.18

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,24 @@
1
+ ## Version 0.0.18
2
+
3
+ * Term's end attribute is now finish
4
+ * Event's end attribute is now finish
5
+ * Evening's evening\_id attribute is now id
6
+ * DueBadge's totals attribute is now a method (totals are calculated each time rather than during initialization)
7
+ * Added exception ArgumentIsInvalid (raised when argument.valid? is false when updating through the API)
8
+ * The following models now use active\_attr:
9
+ * Activity, Activity::File, Activity::Badge and Activity::Version
10
+ * ApiAccess
11
+ * DueBadges
12
+ * Evening and Evening::Activity
13
+ * Event
14
+ * Grouping
15
+ * Member
16
+ * RegisterData
17
+ * RegisterField
18
+ * Role
19
+ * Section and Section::FlexiRecord
20
+ * Term
21
+
1
22
  ## Version 0.0.17
2
23
 
3
24
  * Fix try method is undefined
data/README.md CHANGED
@@ -7,6 +7,10 @@ Master [![Build Status](https://secure.travis-ci.org/robertgauld/osm.png?branch=
7
7
 
8
8
  Staging [![Build Status](https://secure.travis-ci.org/robertgauld/osm.png?branch=staging)](http://travis-ci.org/robertgauld/osm)
9
9
 
10
+ This project also uses gemnasium to help ensure that the current version of libraries are being used.
11
+
12
+ Master [![Dependency Status](https://gemnasium.com/robertgauld/osm.png)](https://gemnasium.com/robertgauld/osm)
13
+
10
14
 
11
15
  ## OSM
12
16
 
@@ -0,0 +1,15 @@
1
+ class ArrayOfValidator < ActiveModel::EachValidator
2
+ def validate_each(record, attribute, value)
3
+ record.errors.add(attribute, 'must be an Array') unless value.is_a?(Array)
4
+ value.each do |value_item|
5
+ unless value_item.is_a?(options[:item_type])
6
+ record.errors.add(attribute, "items in the Array must be a #{options[:item_type].name}")
7
+ else
8
+ # We don't want to check the item is valid if it's the wrong type
9
+ if !options[:item_valid].nil? && (value_item.valid? != options[:item_valid])
10
+ record.errors.add(attribute, 'contains an invalid item')
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ class HashValidator < ActiveModel::EachValidator
2
+ def validate_each(record, attribute, value)
3
+ record.errors.add(attribute, 'must be a Hash') unless value.is_a?(Hash)
4
+
5
+ value.each do |k, v|
6
+ if options[:key_type]
7
+ record.errors.add(attribute, "keys must be a #{options[:key_type].name}") unless k.is_a?(options[:key_type])
8
+ end
9
+
10
+ if options[:key_in]
11
+ record.errors.add(attribute, "keys must be in #{options[:key_in].inspect}") unless options[:key_in].include?(k)
12
+ end
13
+
14
+
15
+ if options[:value_type]
16
+ record.errors.add(attribute, "values must be a #{options[:value_type].name}") unless v.is_a?(options[:value_type])
17
+ end
18
+
19
+ if options[:value_in]
20
+ record.errors.add(attribute, "values must be in #{options[:value_in].inspect}") unless options[:value_in].include?(v)
21
+ end
22
+ end
23
+ end
24
+ end
data/lib/osm.rb CHANGED
@@ -1,17 +1,22 @@
1
- require File.join(File.dirname(__FILE__), '..', 'version')
2
- Dir[File.join(File.dirname(__FILE__) , 'osm', '*.rb')].each {|file| require file }
3
-
1
+ require 'active_attr'
4
2
  require 'date'
5
3
 
6
-
7
4
  module Osm
8
5
  OSM_EPOCH_S = '1970-01-01'
9
6
  OSM_DATE_FORMAT = '%Y-%m-%d'
10
7
  OSM_DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'
8
+ OSM_TIME_REGEX = /\A(?:[0-1][0-9]|2[0-3]):[0-5][0-9]\Z/
9
+ end
10
+
11
+ require File.join(File.dirname(__FILE__), '..', 'version')
12
+ Dir[File.join(File.dirname(__FILE__) , '*_validator.rb')].each {|file| require file }
13
+ Dir[File.join(File.dirname(__FILE__) , 'osm', '*.rb')].each {|file| require file }
11
14
 
15
+
16
+ module Osm
12
17
  class Error < Exception; end
13
18
  class ConnectionError < Error; end
14
-
19
+ class ArgumentIsInvalid < ArgumentError; end
15
20
 
16
21
  private
17
22
  def self.make_array_of_symbols(array)
@@ -81,12 +86,4 @@ module Osm
81
86
  hash_out
82
87
  end
83
88
 
84
- def self.is_array_of?(ar, ty)
85
- return false unless ar.is_a?(Array)
86
- ar.each do |it|
87
- return false unless it.is_a?(ty)
88
- end
89
- return true
90
- end
91
-
92
- end
89
+ end # Module
@@ -1,83 +1,105 @@
1
1
  module Osm
2
2
 
3
3
  class Activity
4
+ class Badge; end # Ensure the constant exists for the validators
5
+ class File; end # Ensure the constant exists for the validators
6
+ class Version; end # Ensure the constant exists for the validators
4
7
 
5
- attr_reader :id, :version, :group_id, :user_id, :title, :description, :resources, :instructions, :running_time, :location, :shared, :rating, :editable, :deletable, :used, :versions, :sections, :tags, :files, :badges
6
- # @!attribute [r] id
8
+ include ::ActiveAttr::MassAssignmentSecurity
9
+ include ::ActiveAttr::Model
10
+
11
+ # @!attribute [rw] id
7
12
  # @return [Fixnum] the id for the activity
8
- # @!attribute [r] version
13
+ # @!attribute [rw] version
9
14
  # @return [Fixnum] the version of the activity
10
- # @!attribute [r] group_id
15
+ # @!attribute [rw] group_id
11
16
  # @return [Fixnum] the group_id
12
- # @!attribute [r] user_id
17
+ # @!attribute [rw] user_id
13
18
  # @return [Fixnum] the user_id of the creator of the activity
14
- # @!attribute [r] title
19
+ # @!attribute [rw] title
15
20
  # @return [String] the activity's title
16
- # @!attribute [r] description
21
+ # @!attribute [rw] description
17
22
  # @return [String] the description of the activity
18
- # @!attribute [r] resources
23
+ # @!attribute [rw] resources
19
24
  # @return [String] resources required to do the activity
20
- # @!attribute [r] instructions
25
+ # @!attribute [rw] instructions
21
26
  # @return [String] instructions for doing the activity
22
- # @!attribute [r] running_time
27
+ # @!attribute [rw] running_time
23
28
  # @return [Fixnum] duration of the activity in minutes
24
- # @!attribute [r] location
29
+ # @!attribute [rw] location
25
30
  # @return [Symbol] :indoors, :outdoors or :both
26
- # @!attribute [r] shared
31
+ # @!attribute [rw] shared
27
32
  # @return [Fixnum] 2 - Public, 0 - Private
28
- # @!attribute [r] rating
33
+ # @!attribute [rw] rating
29
34
  # @return [Fixnum] ?
30
- # @!attribute [r] editable
35
+ # @!attribute [rw] editable
31
36
  # @return [Boolean] Wether the current API user can edit this activity
32
- # @!attribute [r] deletable
37
+ # @!attribute [rw] deletable
33
38
  # @return [Boolean] Wether the current API user can delete this activity
34
- # @!attribute [r] used
39
+ # @!attribute [rw] used
35
40
  # @return [Fixnum] How many times this activity has been used (total accross all of OSM)
36
- # @!attribute [r] versions
41
+ # @!attribute [rw] versions
37
42
  # @return [Array<Osm::Activity::Version>]
38
- # @!attribute [r] sections
43
+ # @!attribute [rw] sections
39
44
  # @return [Array<Symbol>] the sections the activity is appropriate for
40
- # @!attribute [r] tags
45
+ # @!attribute [rw] tags
41
46
  # @return [Array<String>] the tags attached to the activity
42
- # @!attribute [r] files
47
+ # @!attribute [rw] files
43
48
  # @return [Array<Osm::Activity::File>
44
- # @!attribute [r] badges
49
+ # @!attribute [rw] badges
45
50
  # @return [Array<Osm::Activity::Badge>
46
51
 
52
+ attribute :id, :type => Integer
53
+ attribute :version, :type => Integer
54
+ attribute :group_id, :type => Integer
55
+ attribute :user_id, :type => Integer
56
+ attribute :title, :type => String
57
+ attribute :description, :type => String
58
+ attribute :resources, :type => String
59
+ attribute :instructions, :type => String
60
+ attribute :running_time, :type => Integer
61
+ attribute :location
62
+ attribute :shared, :type => Integer
63
+ attribute :rating, :type => Integer
64
+ attribute :editable, :type => Boolean
65
+ attribute :deletable, :type => Boolean
66
+ attribute :used, :type => Integer
67
+ attribute :versions, :default => []
68
+ attribute :sections, :default => []
69
+ attribute :tags, :default => []
70
+ attribute :files, :default => []
71
+ attribute :badges, :default => []
47
72
 
48
- # Initialize a new Activity
49
- # @param [Hash] attributes the hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
50
- def initialize(attributes={})
51
- [:id, :group_id, :user_id].each do |attribute|
52
- it = attributes[attribute]
53
- raise ArgumentError, ":#{attribute} must be nil or a Fixnum > 0" unless it.nil? || (it.is_a?(Fixnum) && it > 0)
54
- end
55
- [:version, :running_time, :shared].each do |attribute|
56
- it = attributes[attribute]
57
- raise ArgumentError, ":#{attribute} must be nil or a Fixnum >= 0" unless it.nil? || (it.is_a?(Fixnum) && it >= 0)
58
- end
73
+ attr_accessible :id, :version, :group_id, :user_id, :title, :description, :resources, :instructions, :running_time, :location, :shared, :rating, :editable, :deletable, :used, :versions, :sections, :tags, :files, :badges
59
74
 
60
- [:title, :description, :resources, :instructions].each do |attribute|
61
- it = attributes[attribute]
62
- raise ArgumentError, ":#{attribute} must be nil or a String" unless it.nil? || it.is_a?(String)
63
- end
75
+ validates_numericality_of :id, :only_integer=>true, :greater_than=>0
76
+ validates_numericality_of :version, :only_integer=>true, :greater_than_or_equal_to=>0
77
+ validates_numericality_of :group_id, :only_integer=>true, :greater_than=>0
78
+ validates_numericality_of :user_id, :only_integer=>true, :greater_than=>0
79
+ validates_numericality_of :running_time, :only_integer=>true, :greater_than_or_equal_to=>0
80
+ validates_numericality_of :shared, :only_integer=>true, :greater_than_or_equal_to=>0
81
+ validates_numericality_of :rating, :only_integer=>true
82
+ validates_numericality_of :used, :only_integer=>true
83
+ validates_presence_of :title
84
+ validates_presence_of :description
85
+ validates_presence_of :resources
86
+ validates_presence_of :instructions
87
+ validates_inclusion_of :editable, :in => [true, false]
88
+ validates_inclusion_of :deletable, :in => [true, false]
89
+ validates_inclusion_of :location, :in => [:indoors, :outdoors, :both], :message => 'is not a valid location'
64
90
 
65
- raise ArgumentError, ':location must be either :indoors, :outdoors or :both' unless [:indoors, :outdoors, :both].include?(attributes[:location])
66
91
 
67
- raise ArgumentError, ':editable must be a Boolean' unless attributes[:editable].is_a?(TrueClass) || attributes[:editable].is_a?(FalseClass)
68
- raise ArgumentError, ':deletable must be a Boolean' unless attributes[:deletable].is_a?(TrueClass) || attributes[:deletable].is_a?(FalseClass)
92
+ validates :sections, :array_of => {:item_type => Symbol}
93
+ validates :tags, :array_of => {:item_type => String}
94
+ validates :badges, :array_of => {:item_type => Osm::Activity::Badge, :item_valid => true}
95
+ validates :files, :array_of => {:item_type => Osm::Activity::File, :item_valid => true}
96
+ validates :versions, :array_of => {:item_type => Osm::Activity::Version, :item_valid => true}
69
97
 
70
- raise ArgumentError, ':rating must be a FixNum' unless attributes[:rating].is_a?(Fixnum)
71
- raise ArgumentError, ':used must be a FixNum' unless attributes[:used].is_a?(Fixnum)
72
98
 
73
- raise ArgumentError, ':sections must be an Array of Symbol' unless Osm::is_array_of?(attributes[:sections], Symbol)
74
- raise ArgumentError, ':tags must be an Array of String' unless Osm::is_array_of?(attributes[:tags], String)
75
- raise ArgumentError, ':versions must be an Array of Osm::Activity::Version' unless Osm::is_array_of?(attributes[:versions], Osm::Activity::Version)
76
- raise ArgumentError, ':files must be an Array of Osm::Activity::File' unless Osm::is_array_of?(attributes[:files], Osm::Activity::File)
77
- raise ArgumentError, ':badges must be an Array of Osm::Activity::Badge' unless Osm::is_array_of?(attributes[:badges], Osm::Activity::Badge)
99
+ # @!method initialize
100
+ # Initialize a new Term
101
+ # @param [Hash] attributes the hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
78
102
 
79
- attributes.each { |k,v| instance_variable_set("@#{k}", v) }
80
- end
81
103
 
82
104
  # Initialize a new Activity from api data
83
105
  # @param [Hash] data the hash of data provided by the API
@@ -121,29 +143,35 @@ module Osm
121
143
 
122
144
  private
123
145
  class File
124
- attr_reader :id, :activity_id, :file_name, :name
125
- # @!attribute [r] id
146
+ include ::ActiveAttr::MassAssignmentSecurity
147
+ include ::ActiveAttr::Model
148
+
149
+ # @!attribute [rw] id
126
150
  # @return [Fixnum] the OSM ID for the file
127
- # @!attribute [r] activity_id
151
+ # @!attribute [rw] activity_id
128
152
  # @return [Fixnum] the OSM ID for the activity
129
- # @!attribute [r] file_name
153
+ # @!attribute [rw] file_name
130
154
  # @return [String] the file name of the file
131
- # @!attribute [r] name
155
+ # @!attribute [rw] name
132
156
  # @return [String] the name of the file (more human readable than file_name)
133
157
 
134
- # Initialize a new File
135
- # @param [Hash] attributes the hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
136
- def initialize(attributes={})
137
- [:file_name, :name].each do |attribute|
138
- raise ArgumentError, ":#{attribute} must a String" unless attributes[attribute].is_a?(String)
139
- end
140
- [:id, :activity_id].each do |attribute|
141
- it = attributes[attribute]
142
- raise ArgumentError, ":#{attribute} must be nil or a Fixnum > 0" unless it.nil? || (it.is_a?(Fixnum) && it > 0)
143
- end
144
-
145
- attributes.each { |k,v| instance_variable_set("@#{k}", v) }
146
- end
158
+ attribute :id, :type => Integer
159
+ attribute :activity_id, :type => Integer
160
+ attribute :file_name, :type => String
161
+ attribute :name, :type => String
162
+
163
+ attr_accessible :id, :activity_id, :file_name, :name
164
+
165
+ validates_numericality_of :id, :only_integer=>true, :greater_than=>0
166
+ validates_numericality_of :activity_id, :only_integer=>true, :greater_than=>0
167
+ validates_presence_of :file_name
168
+ validates_presence_of :name
169
+
170
+
171
+ # @!method initialize
172
+ # Initialize a new Term
173
+ # @param [Hash] attributes the hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
174
+
147
175
 
148
176
  # Initialize a new File from api data
149
177
  # @param [Hash] data the hash of data provided by the API
@@ -156,37 +184,49 @@ module Osm
156
184
  })
157
185
  end
158
186
 
159
- end # Activity::File
187
+ end # Class Activity::File
160
188
 
161
189
  class Badge
162
- attr_reader :activity_id, :section_type, :type, :badge, :requirement, :label
163
- # @!attribute [r] activity_id
190
+ include ::ActiveAttr::MassAssignmentSecurity
191
+ include ::ActiveAttr::Model
192
+
193
+ # @!attribute [rw] activity_id
164
194
  # @return [Fixnum] the activity being done
165
- # @!attribute [r] section_type
195
+ # @!attribute [rw] section_type
166
196
  # @return [Symbol] the section the badge 'belongs' to
167
- # @!attribute [r] type
197
+ # @!attribute [rw] type
168
198
  # @return [Symbol] the type of badge
169
- # @!attribute [r] badge
199
+ # @!attribute [rw] badge
170
200
  # @return [String] short name of the badge
171
- # @!attribute [r] requirement
201
+ # @!attribute [rw] requirement
172
202
  # @return [String] OSM reference to this badge requirement
173
- # @!attribute [r] label
203
+ # @!attribute [rw] label
174
204
  # @return [String] human readable label for the requirement
175
205
 
176
- # Initialize a new Badge
177
- # @param [Hash] attributes the hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
178
- def initialize(attributes={})
179
- raise ArgumentError, ':activity_id must be nil or a Fixnum > 0' unless attributes[:activity_id].nil? || (attributes[:activity_id].is_a?(Fixnum) && attributes[:activity_id] > 0)
180
- [:type, :section_type].each do |attribute|
181
- raise ArgumentError, ":#{attribute} must be a Symbol" unless attributes[attribute].is_a?(Symbol)
182
- end
183
- [:label, :requirement, :badge].each do |attribute|
184
- raise ArgumentError, ":#{attribute} must a String" unless attributes[attribute].is_a?(String)
185
- end
186
-
187
- attributes.each { |k,v| instance_variable_set("@#{k}", v) }
206
+ attribute :activity_id, :type => Integer
207
+ attribute :section_type
208
+ attribute :type
209
+ attribute :badge, :type => String
210
+ attribute :requirement, :type => String
211
+ attribute :label, :type => String
212
+
213
+ attr_accessible :activity_id, :section_type, :type, :badge, :requirement, :label
214
+
215
+ validates_numericality_of :activity_id, :only_integer=>true, :greater_than=>0
216
+ validates_presence_of :badge
217
+ validates_presence_of :requirement
218
+ validates_presence_of :label
219
+
220
+ validates_each :type, :section_type do |record, attr, value|
221
+ record.errors.add(attr, 'must be a Symbol') unless value.is_a?(Symbol)
188
222
  end
189
223
 
224
+
225
+ # @!method initialize
226
+ # Initialize a new Badge
227
+ # @param [Hash] attributes the hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
228
+
229
+
190
230
  # Initialize a new Badge from api data
191
231
  # @param [Hash] data the hash of data provided by the API
192
232
  def self.from_api(data)
@@ -200,29 +240,38 @@ module Osm
200
240
  })
201
241
  end
202
242
 
203
- end # Activity::Badge
243
+ end # Class Activity::Badge
204
244
 
205
245
  class Version
206
- attr_reader :version, :created_by, :created_by_name, :label
207
- # @!attribute [r] version
246
+ include ::ActiveAttr::MassAssignmentSecurity
247
+ include ::ActiveAttr::Model
248
+
249
+ # @!attribute [rw] version
208
250
  # @return [Fixnum] the version of the activity
209
- # @!attribute [r] created_by
251
+ # @!attribute [rw] created_by
210
252
  # @return [Fixnum] the OSM user ID of the person who created this version
211
- # @!attribute [r] created_by_name
253
+ # @!attribute [rw] created_by_name
212
254
  # @return [String] the aname of the OSM user who created this version
213
- # @!attribute [r] label
255
+ # @!attribute [rw] label
214
256
  # @return [String] the human readable label to use for this version
215
257
 
216
- # Initialize a new Version
217
- # @param [Hash] attributes the hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
218
- def initialize(attributes={})
219
- raise ArgumentError, ':version must be nil or a Fixnum > 0' unless attributes[:version].nil? || (attributes[:version].is_a?(Fixnum) && attributes[:version] >= 0)
220
- raise ArgumentError, ':created_by must be nil or a Fixnum >= 0' unless attributes[:created_by].nil? || (attributes[:created_by].is_a?(Fixnum) && attributes[:created_by] > 0)
221
- raise ArgumentError, ':created_by_name must be nil or a String' unless attributes[:created_by_name].nil? || attributes[:created_by_name].is_a?(String)
222
- raise ArgumentError, ':label must be nil or a String' unless attributes[:label].nil? || attributes[:label].is_a?(String)
258
+ attribute :version, :type => Integer
259
+ attribute :created_by, :type => Integer
260
+ attribute :created_by_name, :type => String
261
+ attribute :label, :type => String
262
+
263
+ attr_accessible :version, :created_by, :created_by_name, :label
264
+
265
+ validates_numericality_of :version, :only_integer=>true, :greater_than_or_equal_to=>0
266
+ validates_numericality_of :created_by, :only_integer=>true, :greater_than=>0
267
+ validates_presence_of :created_by_name
268
+ validates_presence_of :label
269
+
270
+
271
+ # @!method initialize
272
+ # Initialize a new Version
273
+ # @param [Hash] attributes the hash of attributes (see attributes for descriptions, use Symbol of attribute name as the key)
223
274
 
224
- attributes.each { |k,v| instance_variable_set("@#{k}", v) }
225
- end
226
275
 
227
276
  # Initialize a new Version from api data
228
277
  # @param [Hash] data the hash of data provided by the API
@@ -235,8 +284,8 @@ module Osm
235
284
  })
236
285
  end
237
286
 
238
- end # Activity::Version
287
+ end # Class Activity::Version
239
288
 
240
- end # Activity
289
+ end # Class Activity
241
290
 
242
291
  end # Module