aenea 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +39 -0
  3. data/Rakefile +24 -0
  4. data/app/assets/config/aenea_manifest.js +0 -0
  5. data/app/helpers/inline_boolean_input.rb +9 -0
  6. data/app/helpers/markdown_input.rb +21 -0
  7. data/app/helpers/non_input_input.rb +7 -0
  8. data/app/models/concerns/acts_as_only_flagged.rb +65 -0
  9. data/app/models/concerns/can_be_inactive.rb +8 -0
  10. data/app/models/concerns/has_external_id.rb +9 -0
  11. data/app/models/concerns/has_obfuscated_id.rb +51 -0
  12. data/app/models/concerns/model.rb +51 -0
  13. data/app/models/concerns/model/belongs_to.rb +38 -0
  14. data/app/models/concerns/model/enum.rb +24 -0
  15. data/app/models/concerns/model/has_many.rb +127 -0
  16. data/app/models/concerns/model/has_one.rb +77 -0
  17. data/app/models/concerns/sluggable.rb +7 -0
  18. data/app/models/countries.rb +278 -0
  19. data/app/models/country_validator.rb +10 -0
  20. data/app/models/database_function_helper.rb +88 -0
  21. data/app/models/google_maps_api.rb +19 -0
  22. data/app/models/google_maps_api/geocode.rb +29 -0
  23. data/app/models/google_maps_api/time_zone.rb +29 -0
  24. data/app/models/json_api.rb +16 -0
  25. data/app/models/phone_number_validator.rb +10 -0
  26. data/app/models/us_state_validator.rb +10 -0
  27. data/app/models/us_states.rb +75 -0
  28. data/app/models/zip_code_validator.rb +12 -0
  29. data/lib/aenea.rb +12 -0
  30. data/lib/aenea/active_admin.rb +23 -0
  31. data/lib/aenea/active_admin/index_as_table.rb +9 -0
  32. data/lib/aenea/active_admin/index_as_table/sortable_columns.rb +29 -0
  33. data/lib/aenea/active_admin/resource_controller.rb +9 -0
  34. data/lib/aenea/active_admin/resource_controller/find_sluggable.rb +21 -0
  35. data/lib/aenea/active_admin/resource_dsl.rb +11 -0
  36. data/lib/aenea/active_admin/resource_dsl/sortable_actions.rb +53 -0
  37. data/lib/aenea/active_admin/resource_dsl/use_parent_actions.rb +79 -0
  38. data/lib/aenea/date.rb +14 -0
  39. data/lib/aenea/engine.rb +20 -0
  40. data/lib/aenea/enum.rb +13 -0
  41. data/lib/aenea/enum/changes.rb +61 -0
  42. data/lib/aenea/enum/ext.rb +68 -0
  43. data/lib/aenea/enum/groups.rb +53 -0
  44. data/lib/aenea/markdown_attr.rb +43 -0
  45. data/lib/aenea/time.rb +9 -0
  46. data/lib/aenea/time_of_day.rb +41 -0
  47. data/lib/aenea/time_window.rb +86 -0
  48. data/lib/aenea/version.rb +3 -0
  49. data/lib/tasks/aenea_tasks.rake +4 -0
  50. metadata +203 -0
@@ -0,0 +1,77 @@
1
+ module Model
2
+ module HasOne
3
+ extend ActiveSupport::Concern
4
+
5
+ class Association
6
+ attr_reader :target, :assoc
7
+
8
+ def initialize(target, assoc, options = {})
9
+ @target = target
10
+ @assoc = assoc.to_sym
11
+
12
+ class_name = options[:class_name] || assoc.to_s.camelize
13
+ klass = class_name.constantize
14
+
15
+ builder_method_name = "build_#{assoc}".to_sym
16
+ validate_method_name = "validate_associated_#{assoc}".to_sym
17
+
18
+ target.send :attr_accessor, assoc
19
+ define_builder builder_method_name, assoc, klass
20
+ define_attributes_writer builder_method_name
21
+ define_present_method assoc
22
+ define_nil_method assoc
23
+ define_validate_method validate_method_name, assoc
24
+
25
+ if validate_options = options[:validate]
26
+ target.validate validate_method_name, validate_options.is_a?(Hash) ? validate_options : {}
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def define_builder(builder_method_name, assoc, klass)
33
+ # def build_thing(attrs = {})
34
+ target.send :define_method, builder_method_name do |attrs = {}|
35
+ send "#{assoc}=", klass.new(attrs)
36
+ end
37
+ end
38
+
39
+ def define_attributes_writer(builder_method_name)
40
+ # def thing_attributes=(params)
41
+ target.send :define_method, "#{assoc}_attributes=" do |params|
42
+ send builder_method_name, params
43
+ end
44
+ end
45
+
46
+ def define_present_method(assoc)
47
+ # def things_present?
48
+ target.send :define_method, "#{assoc}_present?" do
49
+ send(assoc).present?
50
+ end
51
+ end
52
+
53
+ def define_nil_method(assoc)
54
+ # def things_empty?
55
+ target.send :define_method, "#{assoc}_nil?" do
56
+ send(assoc).nil?
57
+ end
58
+ end
59
+
60
+ def define_validate_method(validate_method_name, assoc)
61
+ # def validate_associated_thing
62
+ target.send :define_method, validate_method_name do
63
+ return unless obj = send(assoc)
64
+ errors.add assoc, 'is invalid' unless obj.valid?
65
+ end
66
+ end
67
+ end
68
+
69
+ module ClassMethods
70
+ def has_one(name, options = {})
71
+ (self.associations_registry ||= {})[name] = :has_one
72
+
73
+ Association.new self, name, options
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,7 @@
1
+ module Sluggable
2
+ extend ActiveSupport::Concern
3
+
4
+ def to_param
5
+ url
6
+ end
7
+ end
@@ -0,0 +1,278 @@
1
+ module Countries
2
+ # https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3
3
+ VALUES = [
4
+ ['ABW', 'Aruba'],
5
+ ['AFG', 'Afghanistan'],
6
+ ['AGO', 'Angola'],
7
+ ['AIA', 'Anguilla'],
8
+ ['ALA', 'Åland Islands'],
9
+ ['ALB', 'Albania'],
10
+ ['AND', 'Andorra'],
11
+ ['ARE', 'United Arab Emirates'],
12
+ ['ARG', 'Argentina'],
13
+ ['ARM', 'Armenia'],
14
+ ['ASM', 'American Samoa'],
15
+ ['ATA', 'Antarctica'],
16
+ ['ATF', 'French Southern Territories'],
17
+ ['ATG', 'Antigua and Barbuda'],
18
+ ['AUS', 'Australia'],
19
+ ['AUT', 'Austria'],
20
+ ['AZE', 'Azerbaijan'],
21
+ ['BDI', 'Burundi'],
22
+ ['BEL', 'Belgium'],
23
+ ['BEN', 'Benin'],
24
+ ['BES', 'Bonaire, Sint Eustatius and Saba'],
25
+ ['BFA', 'Burkina Faso'],
26
+ ['BGD', 'Bangladesh'],
27
+ ['BGR', 'Bulgaria'],
28
+ ['BHR', 'Bahrain'],
29
+ ['BHS', 'Bahamas'],
30
+ ['BIH', 'Bosnia and Herzegovina'],
31
+ ['BLM', 'Saint Barthélemy'],
32
+ ['BLR', 'Belarus'],
33
+ ['BLZ', 'Belize'],
34
+ ['BMU', 'Bermuda'],
35
+ ['BOL', 'Bolivia, Plurinational State of'],
36
+ ['BRA', 'Brazil'],
37
+ ['BRB', 'Barbados'],
38
+ ['BRN', 'Brunei Darussalam'],
39
+ ['BTN', 'Bhutan'],
40
+ ['BVT', 'Bouvet Island'],
41
+ ['BWA', 'Botswana'],
42
+ ['CAF', 'Central African Republic'],
43
+ ['CAN', 'Canada'],
44
+ ['CCK', 'Cocos (Keeling) Islands'],
45
+ ['CHE', 'Switzerland'],
46
+ ['CHL', 'Chile'],
47
+ ['CHN', 'China'],
48
+ ['CIV', 'Côte d\'Ivoire'],
49
+ ['CMR', 'Cameroon'],
50
+ ['COD', 'Congo, the Democratic Republic of the'],
51
+ ['COG', 'Congo'],
52
+ ['COK', 'Cook Islands'],
53
+ ['COL', 'Colombia'],
54
+ ['COM', 'Comoros'],
55
+ ['CPV', 'Cabo Verde'],
56
+ ['CRI', 'Costa Rica'],
57
+ ['CUB', 'Cuba'],
58
+ ['CUW', 'Curaçao'],
59
+ ['CXR', 'Christmas Island'],
60
+ ['CYM', 'Cayman Islands'],
61
+ ['CYP', 'Cyprus'],
62
+ ['CZE', 'Czechia'],
63
+ ['DEU', 'Germany'],
64
+ ['DJI', 'Djibouti'],
65
+ ['DMA', 'Dominica'],
66
+ ['DNK', 'Denmark'],
67
+ ['DOM', 'Dominican Republic'],
68
+ ['DZA', 'Algeria'],
69
+ ['ECU', 'Ecuador'],
70
+ ['EGY', 'Egypt'],
71
+ ['ERI', 'Eritrea'],
72
+ ['ESH', 'Western Sahara'],
73
+ ['ESP', 'Spain'],
74
+ ['EST', 'Estonia'],
75
+ ['ETH', 'Ethiopia'],
76
+ ['FIN', 'Finland'],
77
+ ['FJI', 'Fiji'],
78
+ ['FLK', 'Falkland Islands (Malvinas)'],
79
+ ['FRA', 'France'],
80
+ ['FRO', 'Faroe Islands'],
81
+ ['FSM', 'Micronesia, Federated States of'],
82
+ ['GAB', 'Gabon'],
83
+ ['GBR', 'United Kingdom'],
84
+ ['GEO', 'Georgia'],
85
+ ['GGY', 'Guernsey'],
86
+ ['GHA', 'Ghana'],
87
+ ['GIB', 'Gibraltar'],
88
+ ['GIN', 'Guinea'],
89
+ ['GLP', 'Guadeloupe'],
90
+ ['GMB', 'Gambia'],
91
+ ['GNB', 'Guinea-Bissau'],
92
+ ['GNQ', 'Equatorial Guinea'],
93
+ ['GRC', 'Greece'],
94
+ ['GRD', 'Grenada'],
95
+ ['GRL', 'Greenland'],
96
+ ['GTM', 'Guatemala'],
97
+ ['GUF', 'French Guiana'],
98
+ ['GUM', 'Guam'],
99
+ ['GUY', 'Guyana'],
100
+ ['HKG', 'Hong Kong'],
101
+ ['HMD', 'Heard Island and McDonald Islands'],
102
+ ['HND', 'Honduras'],
103
+ ['HRV', 'Croatia'],
104
+ ['HTI', 'Haiti'],
105
+ ['HUN', 'Hungary'],
106
+ ['IDN', 'Indonesia'],
107
+ ['IMN', 'Isle of Man'],
108
+ ['IND', 'India'],
109
+ ['IOT', 'British Indian Ocean Territory'],
110
+ ['IRL', 'Ireland'],
111
+ ['IRN', 'Iran, Islamic Republic of'],
112
+ ['IRQ', 'Iraq'],
113
+ ['ISL', 'Iceland'],
114
+ ['ISR', 'Israel'],
115
+ ['ITA', 'Italy'],
116
+ ['JAM', 'Jamaica'],
117
+ ['JEY', 'Jersey'],
118
+ ['JOR', 'Jordan'],
119
+ ['JPN', 'Japan'],
120
+ ['KAZ', 'Kazakhstan'],
121
+ ['KEN', 'Kenya'],
122
+ ['KGZ', 'Kyrgyzstan'],
123
+ ['KHM', 'Cambodia'],
124
+ ['KIR', 'Kiribati'],
125
+ ['KNA', 'Saint Kitts and Nevis'],
126
+ ['KOR', 'Korea, Republic of'],
127
+ ['KWT', 'Kuwait'],
128
+ ['LAO', 'Lao People\'s Democratic Republic'],
129
+ ['LBN', 'Lebanon'],
130
+ ['LBR', 'Liberia'],
131
+ ['LBY', 'Libya'],
132
+ ['LCA', 'Saint Lucia'],
133
+ ['LIE', 'Liechtenstein'],
134
+ ['LKA', 'Sri Lanka'],
135
+ ['LSO', 'Lesotho'],
136
+ ['LTU', 'Lithuania'],
137
+ ['LUX', 'Luxembourg'],
138
+ ['LVA', 'Latvia'],
139
+ ['MAC', 'Macao'],
140
+ ['MAF', 'Saint Martin (French part)'],
141
+ ['MAR', 'Morocco'],
142
+ ['MCO', 'Monaco'],
143
+ ['MDA', 'Moldova, Republic of'],
144
+ ['MDG', 'Madagascar'],
145
+ ['MDV', 'Maldives'],
146
+ ['MEX', 'Mexico'],
147
+ ['MHL', 'Marshall Islands'],
148
+ ['MKD', 'Macedonia, the former Yugoslav Republic of'],
149
+ ['MLI', 'Mali'],
150
+ ['MLT', 'Malta'],
151
+ ['MMR', 'Myanmar'],
152
+ ['MNE', 'Montenegro'],
153
+ ['MNG', 'Mongolia'],
154
+ ['MNP', 'Northern Mariana Islands'],
155
+ ['MOZ', 'Mozambique'],
156
+ ['MRT', 'Mauritania'],
157
+ ['MSR', 'Montserrat'],
158
+ ['MTQ', 'Martinique'],
159
+ ['MUS', 'Mauritius'],
160
+ ['MWI', 'Malawi'],
161
+ ['MYS', 'Malaysia'],
162
+ ['MYT', 'Mayotte'],
163
+ ['NAM', 'Namibia'],
164
+ ['NCL', 'New Caledonia'],
165
+ ['NER', 'Niger'],
166
+ ['NFK', 'Norfolk Island'],
167
+ ['NGA', 'Nigeria'],
168
+ ['NIC', 'Nicaragua'],
169
+ ['NIU', 'Niue'],
170
+ ['NLD', 'Netherlands'],
171
+ ['NOR', 'Norway'],
172
+ ['NPL', 'Nepal'],
173
+ ['NRU', 'Nauru'],
174
+ ['NZL', 'New Zealand'],
175
+ ['OMN', 'Oman'],
176
+ ['PAK', 'Pakistan'],
177
+ ['PAN', 'Panama'],
178
+ ['PCN', 'Pitcairn'],
179
+ ['PER', 'Peru'],
180
+ ['PHL', 'Philippines'],
181
+ ['PLW', 'Palau'],
182
+ ['PNG', 'Papua New Guinea'],
183
+ ['POL', 'Poland'],
184
+ ['PRI', 'Puerto Rico'],
185
+ ['PRK', 'Korea, Democratic People\'s Republic of'],
186
+ ['PRT', 'Portugal'],
187
+ ['PRY', 'Paraguay'],
188
+ ['PSE', 'Palestine, State of'],
189
+ ['PYF', 'French Polynesia'],
190
+ ['QAT', 'Qatar'],
191
+ ['REU', 'Réunion'],
192
+ ['ROU', 'Romania'],
193
+ ['RUS', 'Russian Federation'],
194
+ ['RWA', 'Rwanda'],
195
+ ['SAU', 'Saudi Arabia'],
196
+ ['SDN', 'Sudan'],
197
+ ['SEN', 'Senegal'],
198
+ ['SGP', 'Singapore'],
199
+ ['SGS', 'South Georgia and the South Sandwich Islands'],
200
+ ['SHN', 'Saint Helena, Ascension and Tristan da Cunha'],
201
+ ['SJM', 'Svalbard and Jan Mayen'],
202
+ ['SLB', 'Solomon Islands'],
203
+ ['SLE', 'Sierra Leone'],
204
+ ['SLV', 'El Salvador'],
205
+ ['SMR', 'San Marino'],
206
+ ['SOM', 'Somalia'],
207
+ ['SPM', 'Saint Pierre and Miquelon'],
208
+ ['SRB', 'Serbia'],
209
+ ['SSD', 'South Sudan'],
210
+ ['STP', 'Sao Tome and Principe'],
211
+ ['SUR', 'Suriname'],
212
+ ['SVK', 'Slovakia'],
213
+ ['SVN', 'Slovenia'],
214
+ ['SWE', 'Sweden'],
215
+ ['SWZ', 'Swaziland'],
216
+ ['SXM', 'Sint Maarten (Dutch part)'],
217
+ ['SYC', 'Seychelles'],
218
+ ['SYR', 'Syrian Arab Republic'],
219
+ ['TCA', 'Turks and Caicos Islands'],
220
+ ['TCD', 'Chad'],
221
+ ['TGO', 'Togo'],
222
+ ['THA', 'Thailand'],
223
+ ['TJK', 'Tajikistan'],
224
+ ['TKL', 'Tokelau'],
225
+ ['TKM', 'Turkmenistan'],
226
+ ['TLS', 'Timor-Leste'],
227
+ ['TON', 'Tonga'],
228
+ ['TTO', 'Trinidad and Tobago'],
229
+ ['TUN', 'Tunisia'],
230
+ ['TUR', 'Turkey'],
231
+ ['TUV', 'Tuvalu'],
232
+ ['TWN', 'Taiwan, Province of China'],
233
+ ['TZA', 'Tanzania, United Republic of'],
234
+ ['UGA', 'Uganda'],
235
+ ['UKR', 'Ukraine'],
236
+ ['UMI', 'United States Minor Outlying Islands'],
237
+ ['URY', 'Uruguay'],
238
+ ['USA', 'United States of America'],
239
+ ['UZB', 'Uzbekistan'],
240
+ ['VAT', 'Holy See'],
241
+ ['VCT', 'Saint Vincent and the Grenadines'],
242
+ ['VEN', 'Venezuela, Bolivarian Republic of'],
243
+ ['VGB', 'Virgin Islands, British'],
244
+ ['VIR', 'Virgin Islands, U.S.'],
245
+ ['VNM', 'Viet Nam'],
246
+ ['VUT', 'Vanuatu'],
247
+ ['WLF', 'Wallis and Futuna'],
248
+ ['WSM', 'Samoa'],
249
+ ['YEM', 'Yemen'],
250
+ ['ZAF', 'South Africa'],
251
+ ['ZMB', 'Zambia'],
252
+ ['ZWE', 'Zimbabwe'],
253
+ ]
254
+
255
+ def self.select_values
256
+ @select_values ||= VALUES.map {|a| a.reverse }.sort_by(&:first)
257
+ end
258
+
259
+ def self.valid?(code)
260
+ (@codes ||= select_values.map(&:last)).include?(code)
261
+ end
262
+
263
+ def self.[](code)
264
+ (@values ||= Hash[VALUES])[code]
265
+ end
266
+
267
+ def self.usa
268
+ 'USA'
269
+ end
270
+
271
+ def self.usa?(code)
272
+ usa == code
273
+ end
274
+
275
+ def self.non_usa_select_values
276
+ @non_us_select_values ||= select_values.reject {|name, code| usa?(code) }
277
+ end
278
+ end
@@ -0,0 +1,10 @@
1
+ class CountryValidator < ActiveModel::EachValidator
2
+ def validate_each(record, attribute, value)
3
+ if value.blank?
4
+ record.errors[attribute] << 'is required' unless options[:allow_blank] || options[:allow_nil]
5
+ return
6
+ end
7
+
8
+ record.errors[attribute] << (options[:message] || 'is not a valid country') unless Countries.valid?(value)
9
+ end
10
+ end
@@ -0,0 +1,88 @@
1
+ module DatabaseFunctionHelper
2
+ def self.select_function(*args)
3
+ obj = Object.new
4
+ obj.extend(DatabaseFunctionHelper)
5
+
6
+ obj.select_function(*args)
7
+ end
8
+
9
+ def select_function(*args)
10
+ options = args.last.is_a?(Hash) ? args.pop : {}
11
+
12
+ sql = [ 'SELECT', function_sql(*args) ].join(' ')
13
+ results = ActiveRecord::Base.connection.execute(sql)
14
+
15
+ if type = options[:one]
16
+ return nil unless results.first
17
+ return cast_one(type, results.first.values.first)
18
+ elsif type = options[:values]
19
+ return cast_values(type, results)
20
+ end
21
+
22
+ results
23
+ end
24
+
25
+ protected
26
+
27
+ def function_sql(*args)
28
+ function_name = "func_#{args.shift}" # add standard prefix
29
+ args_sql = to_args_sql(*args)
30
+ sql = [ function_name, '(', args_sql, ')' ].join
31
+ Rails.logger.debug sql
32
+
33
+ sql
34
+ end
35
+
36
+ def to_args_sql(*args)
37
+ args.collect do |a|
38
+ case a
39
+ when nil
40
+ 'NULL'
41
+ when true
42
+ "'t'"
43
+ when false
44
+ "'f'"
45
+ else
46
+ if a.is_a? Hash
47
+ [ to_args_sql(a.values.first), '::', a.keys.first.to_s ].join
48
+ elsif a.is_a? Array
49
+ "'{#{a.join(',')}}'"
50
+ else
51
+ "'#{a}'"
52
+ end
53
+ end
54
+ end.join(', ')
55
+ end
56
+
57
+ def cast_one(type, string)
58
+ return nil if string.nil?
59
+
60
+ case type
61
+ when :boolean
62
+ return string == 't'
63
+ when :date
64
+ return Date.parse(string)
65
+ when :datetime
66
+ return Time.parse(string)
67
+ when :decimal
68
+ return BigDecimal.new(string)
69
+ when :float
70
+ return string.to_f
71
+ when :integer
72
+ return string.to_i
73
+ when :time_of_day
74
+ return Tod::TimeOfDay.parse(string)
75
+ when :time_window
76
+ return TimeWindow.parse_tuple(string)
77
+ when :timestamp
78
+ return Time.parse(string)
79
+ end
80
+
81
+ string
82
+ end
83
+
84
+ def cast_values(type, results)
85
+ values = results.values.map(&:first)
86
+ values.collect {|val| cast_one(type, val) }
87
+ end
88
+ end