Class: Relaton::Index::FileIO
- Inherits:
-
Object
- Object
- Relaton::Index::FileIO
- Defined in:
- lib/relaton/index/file_io.rb
Overview
File IO class is used to read and write index files. In searh mode url is used to fetch index from external repository and save it to storage. In index mode url should be nil.
Instance Attribute Summary collapse
-
#pubid_class ⇒ Object
readonly
Returns the value of attribute pubid_class.
-
#url ⇒ Object
readonly
Returns the value of attribute url.
Instance Method Summary collapse
- #check_basic_format(index) ⇒ Object
-
#check_file ⇒ Array<Hash>?
Check if index file exists and is not older than 24 hours.
-
#check_format(index) ⇒ Boolean
Check if index has correct format.
- #check_id_format(index) ⇒ Object
- #deserialize_pubid(index) ⇒ Object
-
#fetch_and_save ⇒ Array<Hash>
Fetch index from external repository and save it to storage.
- #file ⇒ Object
-
#initialize(dir, url, filename, id_keys, pubid_class = nil) ⇒ FileIO
constructor
Initialize FileIO.
- #load_index(yaml, save = false) ⇒ Object
-
#path_to_local_file ⇒ <Type>
Create path to local file.
- #progname ⇒ Object
-
#read ⇒ Array<Hash>
If url is String, check if index file exists and is not older than 24 hours.
-
#read_file ⇒ Array<Hash>
Read index from storage.
-
#remove ⇒ Array
Remove index file from storage.
-
#save(index) ⇒ void
Save index to storage.
- #warn_local_index_error(reason) ⇒ Object
- #warn_remote_index_error(reason) ⇒ Object
Constructor Details
#initialize(dir, url, filename, id_keys, pubid_class = nil) ⇒ FileIO
Initialize FileIO
22 23 24 25 26 27 28 |
# File 'lib/relaton/index/file_io.rb', line 22 def initialize(dir, url, filename, id_keys, pubid_class = nil) @dir = dir @url = url @filename = filename @id_keys = id_keys || [] @pubid_class = pubid_class end |
Instance Attribute Details
#pubid_class ⇒ Object (readonly)
Returns the value of attribute pubid_class.
9 10 11 |
# File 'lib/relaton/index/file_io.rb', line 9 def pubid_class @pubid_class end |
#url ⇒ Object (readonly)
Returns the value of attribute url.
9 10 11 |
# File 'lib/relaton/index/file_io.rb', line 9 def url @url end |
Instance Method Details
#check_basic_format(index) ⇒ Object
84 85 86 87 88 89 |
# File 'lib/relaton/index/file_io.rb', line 84 def check_basic_format(index) return false unless index.is_a? Array keys = %i[file id] index.all? { |item| item.respond_to?(:keys) && item.keys.sort == keys } end |
#check_file ⇒ Array<Hash>?
Check if index file exists and is not older than 24 hours
66 67 68 69 70 71 |
# File 'lib/relaton/index/file_io.rb', line 66 def check_file ctime = Index.config.storage.ctime(file) return unless ctime && ctime > Time.now - 86400 read_file end |
#check_format(index) ⇒ Boolean
Check if index has correct format
80 81 82 |
# File 'lib/relaton/index/file_io.rb', line 80 def check_format(index) check_basic_format(index) && check_id_format(index) end |
#check_id_format(index) ⇒ Object
91 92 93 94 95 96 97 98 |
# File 'lib/relaton/index/file_io.rb', line 91 def check_id_format(index) return true if @id_keys.empty? keys = index.each_with_object(Set.new) do |item, acc| acc.merge item[:id].keys if item[:id].is_a?(Hash) end keys.none? { |k| !@id_keys.include? k } end |
#deserialize_pubid(index) ⇒ Object
112 113 114 115 116 |
# File 'lib/relaton/index/file_io.rb', line 112 def deserialize_pubid(index) return index unless @pubid_class index.map { |r| { id: @pubid_class.create(**r[:id]), file: r[:file] } } end |
#fetch_and_save ⇒ Array<Hash>
Fetch index from external repository and save it to storage
154 155 156 157 158 159 160 161 |
# File 'lib/relaton/index/file_io.rb', line 154 def fetch_and_save resp = StringIO.new(URI(url).read) zip = Zip::InputStream.new resp entry = zip.get_next_entry yaml = entry.get_input_stream.read Util.info "Downloaded index from `#{url}`", progname load_index(yaml, save = true) end |
#file ⇒ Object
48 49 50 |
# File 'lib/relaton/index/file_io.rb', line 48 def file @file ||= url ? path_to_local_file : @filename end |
#load_index(yaml, save = false) ⇒ Object
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/relaton/index/file_io.rb', line 132 def load_index(yaml, save = false) index = YAML.safe_load(yaml, permitted_classes: [Symbol]) save index if save return deserialize_pubid(index) if check_format index if save warn_remote_index_error "Wrong structure of" else warn_local_index_error "Wrong structure of" end rescue Psych::SyntaxError if save warn_remote_index_error "YAML parsing error when reading" else warn_local_index_error "YAML parsing error when reading" end end |
#path_to_local_file ⇒ <Type>
Create path to local file
57 58 59 |
# File 'lib/relaton/index/file_io.rb', line 57 def path_to_local_file File.join(Index.config.storage_dir, ".relaton", @dir, @filename) end |
#progname ⇒ Object
128 129 130 |
# File 'lib/relaton/index/file_io.rb', line 128 def progname @progname ||= "relaton-#{@dir}" end |
#read ⇒ Array<Hash>
If url is String, check if index file exists and is not older than 24
hours. If not, fetch index from external repository and save it to
storage.
If url is true, read index from path to local file. If url is nil, read index from filename.
39 40 41 42 43 44 45 46 |
# File 'lib/relaton/index/file_io.rb', line 39 def read case url when String check_file || fetch_and_save else read_file || [] end end |
#read_file ⇒ Array<Hash>
Read index from storage
105 106 107 108 109 110 |
# File 'lib/relaton/index/file_io.rb', line 105 def read_file yaml = Index.config.storage.read(file) return unless yaml load_index(yaml) || [] end |
#remove ⇒ Array
Remove index file from storage
186 187 188 189 |
# File 'lib/relaton/index/file_io.rb', line 186 def remove Index.config.storage.remove file [] end |
#save(index) ⇒ void
This method returns an undefined value.
Save index to storage
176 177 178 179 |
# File 'lib/relaton/index/file_io.rb', line 176 def save(index) Index.config.storage.write file, index.map { |item| item.transform_values { |value| value.is_a?(Pubid::Core::Identifier::Base) ? value.to_h : value } }.to_yaml end |
#warn_local_index_error(reason) ⇒ Object
118 119 120 121 122 123 124 125 126 |
# File 'lib/relaton/index/file_io.rb', line 118 def warn_local_index_error(reason) Util.info "#{reason} file `#{file}`", progname if url.is_a? String Util.info "Considering `#{file}` file corrupt, re-downloading from `#{url}`", progname else Util.info "Considering `#{file}` file corrupt, removing it.", progname remove end end |
#warn_remote_index_error(reason) ⇒ Object
163 164 165 166 167 |
# File 'lib/relaton/index/file_io.rb', line 163 def warn_remote_index_error(reason) Util.info "#{reason} newly downloaded file `#{file}` at `#{url}`, " \ "the remote index seems to be invalid. Please report this " \ "issue at https://github.com/relaton/relaton-cli.", progname end |