Module: Kernel
- Defined in:
- lib/cocos.rb,
lib/cocos/find_file.rb
Instance Method Summary collapse
-
#_escape_csv(value) ⇒ Object
quote values that incl.
-
#download_blob(url) ⇒ Object
alias_method :read_bin, :read_blob.
-
#download_csv(url, sep: nil) ⇒ Object
note - use explicit download for now.
- #download_data(url) ⇒ Object
- #download_ini(url) ⇒ Object (also: #download_conf)
- #download_json(url) ⇒ Object
- #download_lines(url) ⇒ Object
- #download_tab(url) ⇒ Object
- #download_text(url) ⇒ Object (also: #download_txt)
- #download_yaml(url) ⇒ Object (also: #download_yml)
-
#find_file(name, path:) ⇒ Object
todo/check - expand path and use File.realpath too? or keep “simple” File.join ?.
- #find_file!(name, path:) ⇒ Object
-
#load_env(path = './.env') ⇒ Object
todo/check - change path to *paths= and support more files - why? why not?.
- #parse_csv(str, sep: nil) ⇒ Object
- #parse_data(str) ⇒ Object
- #parse_env(str) ⇒ Object
- #parse_ini(str) ⇒ Object (also: #parse_conf)
- #parse_json(str) ⇒ Object
- #parse_lines(str) ⇒ Object
- #parse_tab(str) ⇒ Object
- #parse_yaml(str) ⇒ Object (also: #parse_yml)
- #read_blob(path) ⇒ Object
-
#read_csv(path, sep: nil) ⇒ Object
todo: add symbolize options a la read_json? - why? why not? add sep options.
-
#read_data(path) ⇒ Object
note: use read_data / parse_data for alternate shortcut for read_csv / parse_csv w/ headers: false returning arrays of strings.
- #read_env(path) ⇒ Object
- #read_ini(path) ⇒ Object (also: #read_conf)
-
#read_json(path) ⇒ Object
todo: add symbolize options ???.
-
#read_lines(path) ⇒ Object
todo/check: remove n (orr or rn) from line ruby (by default) keeps the newline - follow tradition? why? why not? add/offer chomp: true/false option or such - why? why not? see String.lines in rdoc.
- #read_tab(path) ⇒ Object
- #read_text(path) ⇒ Object (also: #read_txt)
-
#read_yaml(path) ⇒ Object
(also: #read_yml)
todo/check: use parse_safeyaml or such? (is default anyway?) - why? why not?.
-
#wget(url, **opts) ⇒ Object
world wide web (www) support.
-
#wget!(url, **opts) ⇒ Object
add alias www_get or web_get - why? why not?.
- #write_blob(path, blob) ⇒ Object
-
#write_csv(path, recs, headers: nil) ⇒ Object
note: for now write_csv expects array of string arrays does NOT support array of hashes for now.
-
#write_json(path, data) ⇒ Object
add writers.
- #write_text(path, text) ⇒ Object (also: #write_txt)
Instance Method Details
#_escape_csv(value) ⇒ Object
quote values that incl. a comma
todo/fix - add more escape/quote checks - why? why not?
check how other csv libs handle value generation
If a field contains
-
a comma (,)
-
a double quote (“)
-
a newline (rn)
then wrap the field in quotes
Inside quoted fields, double every double quote (" → "")
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
# File 'lib/cocos.rb', line 344 def _escape_csv(value) ## auto-convert to string or let code fail on nil or such? value = value.to_s ## note - double double quotes (") for now only ## check ## - escape newline (lf) as \n or keep it literal - why? why not? ## what about \r carriage return (cr) ## ## add value.match?(/\A\s|\s\z/) || ## to preserve leading/trailing spaces in value ??? ## e.g. _a_ becomes "_a_" written out ## ## quote empty strings or keep them empty ## what about nil - for now empty string too ## add nil_value option e.g. 'n/a' or such ## and quote_empty true|false - why? why not? if value.include?(',') || value.include?('"') || value.include?("\n") || value.include?("\r") '"' + value.gsub('"', '""') + '"' else value end end |
#download_blob(url) ⇒ Object
alias_method :read_bin, :read_blob
192 193 194 |
# File 'lib/cocos.rb', line 192 def download_blob( url ) wget!( url ).blob end |
#download_csv(url, sep: nil) ⇒ Object
note - use explicit download for now
71 72 73 74 75 76 77 |
# File 'lib/cocos.rb', line 71 def download_csv( url, sep: nil ) opts = {} opts[:sep] = sep if sep parse_csv( download_text( url ), **opts ) end |
#download_data(url) ⇒ Object
92 93 94 |
# File 'lib/cocos.rb', line 92 def download_data( url ) parse_data( download_text( url )) end |
#download_ini(url) ⇒ Object Also known as: download_conf
153 154 155 |
# File 'lib/cocos.rb', line 153 def download_ini( url ) parse_ini( download_text( url )) end |
#download_json(url) ⇒ Object
121 122 123 |
# File 'lib/cocos.rb', line 121 def download_json( url ) parse_json( download_text( url )) end |
#download_lines(url) ⇒ Object
213 214 215 |
# File 'lib/cocos.rb', line 213 def download_lines( url ) parse_lines( download_text( url )) end |
#download_tab(url) ⇒ Object
106 107 108 |
# File 'lib/cocos.rb', line 106 def download_tab( url ) parse_tab( download_text( url )) end |
#download_text(url) ⇒ Object Also known as: download_txt
175 176 177 |
# File 'lib/cocos.rb', line 175 def download_text( url ) wget!( url ).text end |
#download_yaml(url) ⇒ Object Also known as: download_yml
135 136 137 |
# File 'lib/cocos.rb', line 135 def download_yaml( url ) parse_yaml( download_text( url )) end |
#find_file(name, path:) ⇒ Object
todo/check - expand path and use File.realpath too?
or keep "simple" File.join ?
33 34 35 36 37 38 39 40 41 42 |
# File 'lib/cocos/find_file.rb', line 33 def find_file( name, path: ) return name if File.file?( name ) path.each do |dir| filepath = File.join( dir, name ) return filepath if File.file?( filepath ) end nil ## return nil if not found end |
#find_file!(name, path:) ⇒ Object
18 19 20 21 22 |
# File 'lib/cocos/find_file.rb', line 18 def find_file!( name, path: ) filepath = find_file( name, path: path ) raise Errorno::ENOENT, "file <#{name}> not found; looking in path #{path.inspect}" if filepath.nil? filepath end |
#load_env(path = './.env') ⇒ Object
todo/check - change path to *paths=
and support more files - why? why not?
note - use File.file? instead of File.exist?
will avoid matching directories!
237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/cocos.rb', line 237 def load_env( path='./.env' ) if File.file?( path ) puts "==> loading .env settings..." env = read_env( path ) puts " applying .env settings... (merging into ENV)" pp env ## note: will only add .env setting if NOT present in ENV!!! env.each do |k,v| ENV[k] ||= v end end end |
#parse_csv(str, sep: nil) ⇒ Object
61 62 63 64 65 66 |
# File 'lib/cocos.rb', line 61 def parse_csv( str, sep: nil ) opts = {} opts[:sep] = sep if sep CsvHash.parse( str, **opts ) end |
#parse_data(str) ⇒ Object
88 89 90 |
# File 'lib/cocos.rb', line 88 def parse_data( str ) Csv.parse( str ) end |
#parse_env(str) ⇒ Object
223 224 225 |
# File 'lib/cocos.rb', line 223 def parse_env( str ) EnvParser.load( str ) end |
#parse_ini(str) ⇒ Object Also known as: parse_conf
149 150 151 |
# File 'lib/cocos.rb', line 149 def parse_ini( str ) INI.load( str ) end |
#parse_json(str) ⇒ Object
117 118 119 |
# File 'lib/cocos.rb', line 117 def parse_json( str ) JSON.parse( str ) end |
#parse_lines(str) ⇒ Object
209 210 211 |
# File 'lib/cocos.rb', line 209 def parse_lines( str ) str.lines end |
#parse_tab(str) ⇒ Object
102 103 104 |
# File 'lib/cocos.rb', line 102 def parse_tab( str ) Tab.parse( str ) end |
#parse_yaml(str) ⇒ Object Also known as: parse_yml
131 132 133 |
# File 'lib/cocos.rb', line 131 def parse_yaml( str ) YAML.load( str ) end |
#read_blob(path) ⇒ Object
184 185 186 187 188 |
# File 'lib/cocos.rb', line 184 def read_blob( path ) File.open( path, 'rb' ) do |f| f.read end end |
#read_csv(path, sep: nil) ⇒ Object
todo: add symbolize options a la read_json? - why? why not?
add sep
54 55 56 57 58 59 |
# File 'lib/cocos.rb', line 54 def read_csv( path, sep: nil ) opts = {} opts[:sep] = sep if sep CsvHash.read( path, **opts ) end |
#read_data(path) ⇒ Object
note: use read_data / parse_data
for alternate shortcut for read_csv / parse_csv w/ headers: false
returning arrays of strings
84 85 86 |
# File 'lib/cocos.rb', line 84 def read_data( path ) Csv.read( path ) end |
#read_env(path) ⇒ Object
219 220 221 |
# File 'lib/cocos.rb', line 219 def read_env( path ) parse_env( read_text( path )) end |
#read_ini(path) ⇒ Object Also known as: read_conf
145 146 147 |
# File 'lib/cocos.rb', line 145 def read_ini( path ) parse_ini( read_text( path )) end |
#read_json(path) ⇒ Object
todo: add symbolize options ???
113 114 115 |
# File 'lib/cocos.rb', line 113 def read_json( path ) parse_json( read_text( path )) end |
#read_lines(path) ⇒ Object
todo/check: remove n (orr or rn) from line
ruby (by default) keeps the newline - follow tradition? why? why not?
add/offer chomp: true/false option or such - why? why not?
see String.lines in rdoc
205 206 207 |
# File 'lib/cocos.rb', line 205 def read_lines( path ) read_text( path ).lines end |
#read_tab(path) ⇒ Object
98 99 100 |
# File 'lib/cocos.rb', line 98 def read_tab( path ) Tab.read( path ) end |
#read_text(path) ⇒ Object Also known as: read_txt
164 165 166 167 168 169 170 171 172 173 |
# File 'lib/cocos.rb', line 164 def read_text( path ) ## todo/check: add universal newline mode or such? ## e.g. will always convert all ## newline variants (\n|\r|\n\r) to "universal" \n only ## ## add r:bom - why? why not? File.open( path, 'r:utf-8' ) do |f| f.read end end |
#read_yaml(path) ⇒ Object Also known as: read_yml
todo/check: use parse_safeyaml or such? (is default anyway?) - why? why not?
127 128 129 |
# File 'lib/cocos.rb', line 127 def read_yaml( path ) parse_yaml( read_text( path )) end |
#wget(url, **opts) ⇒ Object
world wide web (www) support
380 381 382 |
# File 'lib/cocos.rb', line 380 def wget( url, **opts ) Webclient.get( url, **opts ) end |
#wget!(url, **opts) ⇒ Object
add alias www_get or web_get - why? why not?
385 386 387 388 389 390 391 392 |
# File 'lib/cocos.rb', line 385 def wget!( url, **opts ) res = Webclient.get( url, **opts ) ## check/todo - use a different exception/error - keep RuntimeError - why? why not? raise RuntimeError, "HTTP #{res.status.code} - #{res.status.}" if res.status.nok? res end |
#write_blob(path, blob) ⇒ Object
271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'lib/cocos.rb', line 271 def write_blob( path, blob ) ### ## todo/check: check if data is Webclient.Response? ## if yes use res.blob/body - why? why not? dirname = File.dirname( path ) FileUtils.mkdir_p( dirname ) unless Dir.exist?( dirname ) File.open( path, 'wb' ) do |f| f.write( blob ) end end |
#write_csv(path, recs, headers: nil) ⇒ Object
note:
for now write_csv expects array of string arrays
does NOT support array of hashes for now
308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'lib/cocos.rb', line 308 def write_csv( path, recs, headers: nil ) dirname = File.dirname( path ) FileUtils.mkdir_p( dirname ) unless Dir.exist?( dirname ) File.open( path, 'w:utf-8' ) do |f| if headers ## e.g. Date,Team 1,FT,HT,Team 2 f.write( headers.map do |header| _escape_csv( header ) end.join(',') ) f.write( "\n" ) end recs.each do |values| buf = values.map do |value| _escape_csv( value ) end.join( ',' ) f.write( buf ) f.write( "\n" ) end end end |
#write_json(path, data) ⇒ Object
add writers
256 257 258 259 260 261 262 263 264 265 266 267 268 |
# File 'lib/cocos.rb', line 256 def write_json( path, data ) ### ## todo/check: check if data is Webclient.Response? ## if yes use res.json - why? why not? dirname = File.dirname( path ) FileUtils.mkdir_p( dirname ) unless Dir.exist?( dirname ) ## note: pretty print/reformat json File.open( path, 'w:utf-8' ) do |f| f.write( JSON.pretty_generate( data )) end end |
#write_text(path, text) ⇒ Object Also known as: write_txt
287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/cocos.rb', line 287 def write_text( path, text ) ### ## todo/check: check if data is Webclient.Response? ## if yes use res.text - why? why not? dirname = File.dirname( path ) FileUtils.mkdir_p( dirname ) unless Dir.exist?( dirname ) File.open( path, 'w:utf-8' ) do |f| f.write( text ) end end |