Class: Yarii::DatafileModel
- Inherits:
-
Object
- Object
- Yarii::DatafileModel
- Extended by:
- ActiveModel::Callbacks, FilePathDefinitions, VariableDefinitions
- Includes:
- ActiveModel::Model, Serializers::YAML
- Defined in:
- app/models/yarii/datafile_model.rb
Constant Summary collapse
- CHECK_BASE_64_REGEXP =
code snippet from Jekyll
/^([A-Za-z0-9+\/]{4})*([A-Za-z0-9+\/]{4}|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==)$/
- PAGINATION_SIZE =
12
Instance Attribute Summary collapse
-
#file_path ⇒ Object
Returns the value of attribute file_path.
-
#key_path ⇒ Object
Returns the value of attribute key_path.
Class Method Summary collapse
- .absolute_path(path) ⇒ Object
- .all(file_path) ⇒ Object
- .find(file_path, key_path) ⇒ Object
- .sanitize_filepath(path) ⇒ Object
Instance Method Summary collapse
- #assign_attributes(new_attributes) ⇒ Object
- #attributes ⇒ Object
- #destroy ⇒ Object
- #file_name ⇒ Object
- #file_stat ⇒ Object
- #id ⇒ Object
- #load_file_from_path ⇒ Object
- #new_record? ⇒ Boolean
- #persisted? ⇒ Boolean
- #posted_datetime ⇒ Object
- #save ⇒ Object
- #update_variables(hash) ⇒ Object
- #variable_names ⇒ Object
Methods included from VariableDefinitions
Methods included from FilePathDefinitions
Methods included from Serializers::YAML
Instance Attribute Details
#file_path ⇒ Object
Returns the value of attribute file_path.
22 23 24 |
# File 'app/models/yarii/datafile_model.rb', line 22 def file_path @file_path end |
#key_path ⇒ Object
Returns the value of attribute key_path.
22 23 24 |
# File 'app/models/yarii/datafile_model.rb', line 22 def key_path @key_path end |
Class Method Details
.absolute_path(path) ⇒ Object
43 44 45 |
# File 'app/models/yarii/datafile_model.rb', line 43 def self.absolute_path(path) sanitize_filepath File.join(self.base_path, self.folder_path, path) end |
.all(file_path) ⇒ Object
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'app/models/yarii/datafile_model.rb', line 56 def self.all(file_path) raise "Missing base path for the #{self.name} content model" if self.base_path.blank? if CHECK_BASE_64_REGEXP.match file_path file_path = Base64::decode64 file_path end file_path = absolute_path(file_path) file_data = File.read(file_path) loaded_variables = {} yaml_data = nil begin yaml_data = ::SafeYAML.load(file_data) end if yaml_data.nil? raise "YAML wasn't loadable" end models = [] if yaml_data.is_a? Array yaml_data.each_with_index do |item, index| models << new(file_path: file_path, key_path: index.to_s).tap do |content_model| content_model.load_file_from_path end end else yaml_data = ActiveSupport::HashWithIndifferentAccess.new(yaml_data) yaml_data.keys.each do |key| models << new(file_path: file_path, key_path: key.to_s).tap do |content_model| content_model.load_file_from_path end end end models end |
.find(file_path, key_path) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'app/models/yarii/datafile_model.rb', line 28 def self.find(file_path, key_path) raise "Missing base path for the #{self.name} content model" if self.base_path.blank? # decode Base64 path if necessary if CHECK_BASE_64_REGEXP.match file_path file_path = Base64::decode64 file_path end file_path = absolute_path(file_path) new(file_path: file_path, key_path: key_path).tap do |content_model| content_model.load_file_from_path end end |
.sanitize_filepath(path) ⇒ Object
47 48 49 50 51 52 53 54 |
# File 'app/models/yarii/datafile_model.rb', line 47 def self.sanitize_filepath(path) if path.include? "../" # TODO: output better error message ;) raise "Nice try, Hacker Dude. You lose." end path end |
Instance Method Details
#assign_attributes(new_attributes) ⇒ Object
203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'app/models/yarii/datafile_model.rb', line 203 def assign_attributes(new_attributes) # Changed from Active Model # (we implement our own method of assigning attributes) if !new_attributes.respond_to?(:stringify_keys) raise ArgumentError, "When assigning attributes, you must pass a hash as an argument." end return if new_attributes.empty? attributes = new_attributes.stringify_keys update_variables(sanitize_for_mass_assignment(attributes)) end |
#attributes ⇒ Object
195 196 197 198 199 200 201 |
# File 'app/models/yarii/datafile_model.rb', line 195 def attributes ret = {} variable_names.each do |var_name| ret[var_name.to_s] = nil end ret end |
#destroy ⇒ Object
143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'app/models/yarii/datafile_model.rb', line 143 def destroy # TODO: what does it mean to destroy a keypath? raise "TBD" run_callbacks :destroy do if persisted? File.delete(file_path) # TODO: figure out a better way to hook in repo updates # Yarii::Repository.current&.remove(file_path) self.file_path = nil true end end end |
#file_name ⇒ Object
173 174 175 |
# File 'app/models/yarii/datafile_model.rb', line 173 def file_name file_path&.split('/')&.last end |
#file_stat ⇒ Object
177 178 179 180 181 |
# File 'app/models/yarii/datafile_model.rb', line 177 def file_stat if persisted? @file_stat ||= File.stat(file_path) end end |
#id ⇒ Object
158 159 160 161 162 163 164 |
# File 'app/models/yarii/datafile_model.rb', line 158 def id if persisted? relative_base = File.join(self.class.base_path, self.class.folder_path) relative_path = file_path.sub(/^#{relative_base}/, '') Base64.encode64(relative_path).strip end end |
#load_file_from_path ⇒ Object
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 |
# File 'app/models/yarii/datafile_model.rb', line 237 def load_file_from_path raise "Missing keypath" if key_path.nil? file_data = File.read(file_path) loaded_variables = {} begin yaml_data = ::SafeYAML.load(file_data) loaded_variables = yaml_data.value_at_keypath(key_path) rescue SyntaxError => e Rails.logger.error "Error: YAML Exception reading #{file_path}: #{e.}" end if loaded_variables.present? update_variables(loaded_variables) end end |
#new_record? ⇒ Boolean
169 170 171 |
# File 'app/models/yarii/datafile_model.rb', line 169 def new_record? !persisted? end |
#persisted? ⇒ Boolean
166 167 168 |
# File 'app/models/yarii/datafile_model.rb', line 166 def persisted? file_path.present? && File.exist?(file_path) end |
#posted_datetime ⇒ Object
183 184 185 186 187 188 189 |
# File 'app/models/yarii/datafile_model.rb', line 183 def posted_datetime if variable_names.include?(:date) && date date.to_datetime elsif persisted? file_stat.mtime end end |
#save ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'app/models/yarii/datafile_model.rb', line 99 def save run_callbacks :save do if file_path.blank? raise "Must supply a file path to save to" end file_data = File.read(file_path) loaded_variables = {} yaml_data = nil begin yaml_data = ::SafeYAML.load(file_data) end if yaml_data.nil? raise "YAML wasn't loadable" end final_data = nil if yaml_data.is_a? Array yaml_data.set_keypath(key_path, as_yaml(as_hash: true)) final_data = yaml_data.to_yaml else yaml_data = ActiveSupport::HashWithIndifferentAccess.new(yaml_data) yaml_data.set_keypath(key_path, as_yaml(as_hash: true)) final_data = yaml_data.to_hash.to_yaml end final_data.sub!(/^---$\n/,'') # strip off the leading dashes File.open(file_path, 'w') do |f| f.write(final_data) end # TODO: figure out a better way to hook in repo updates # Yarii::Repository.current&.add(file_path_to_use) true end end |
#update_variables(hash) ⇒ Object
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 |
# File 'app/models/yarii/datafile_model.rb', line 216 def update_variables(hash) hash.each do |key, value| begin send("#{key}=", value) rescue NoMethodError Rails.logger.warn (":#{key}: is not a defined front matter variable, will be available as read-only") # If an unfamiliar variable is present, allow it to be set as a # read-only value for future serialization, but it still can't be set # via an accessor writer. Kind ugly code, but it works instance_variable_set("@#{key}", value) unless key.to_sym.in? variable_names variable_names << key.to_sym define_singleton_method key.to_sym do instance_variable_get("@#{key}") end end end end end |
#variable_names ⇒ Object
191 192 193 |
# File 'app/models/yarii/datafile_model.rb', line 191 def variable_names @variable_names ||= self.class.variable_names&.dup || [] end |