Module: Textus::Refresh
- Defined in:
- lib/textus/refresh.rb
Constant Summary collapse
- FETCHER_TIMEOUT_SECONDS =
2
Class Method Summary collapse
- .call(store, key, as:) ⇒ Object
-
.normalize_fetcher_result(res, format:) ⇒ Object
Normalize the three accepted fetcher return shapes into the store’s internal body, content representation.
Class Method Details
.call(store, key, as:) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/textus/refresh.rb', line 7 def self.call(store, key, as:) mentry, path, = store.manifest.resolve(key) raise UsageError.new("no fetcher declared for '#{key}'") unless mentry.fetcher before_etag = File.exist?(path) ? Etag.for_file(path) : nil callable = store.registry.fetcher(mentry.fetcher) view = StoreView.new(store) result = begin Timeout.timeout(FETCHER_TIMEOUT_SECONDS) { callable.call(config: mentry.fetcher_config, store: view) } rescue Timeout::Error raise UsageError.new("fetcher '#{mentry.fetcher}' exceeded #{FETCHER_TIMEOUT_SECONDS}s timeout") rescue Textus::Error raise rescue StandardError => e raise UsageError.new("fetcher '#{mentry.fetcher}' raised: #{e.class}: #{e.}") end normalized = normalize_fetcher_result(result, format: mentry.format) envelope = store.put( key, frontmatter: normalized[:frontmatter], body: normalized[:body], content: normalized[:content], as: as, suppress_events: true, ) change = if before_etag.nil? :created elsif envelope["etag"] == before_etag :unchanged else :updated end store.fire_event(:refresh, key: key, envelope: envelope, change: change) unless change == :unchanged envelope end |
.normalize_fetcher_result(res, format:) ⇒ Object
Normalize the three accepted fetcher return shapes into the store’s internal body, content representation. See plan-1.2 §7.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/textus/refresh.rb', line 48 def self.normalize_fetcher_result(res, format:) res = res.transform_keys(&:to_s) if res.is_a?(Hash) res ||= {} fm = res["frontmatter"] body = res["body"] content = res["content"] case format when "markdown" { frontmatter: fm || {}, body: body.to_s, content: nil } when "text" { frontmatter: {}, body: body.to_s, content: nil } when "json", "yaml" if !content.nil? = content.is_a?(Hash) && content["_meta"].is_a?(Hash) ? content["_meta"] : {} { frontmatter: , body: nil, content: content } elsif !body.nil? # Store#put will re-parse and validate the bytes. { frontmatter: {}, body: body.to_s, content: nil } else raise UsageError.new("fetcher for #{format} returned neither content nor body") end else raise UsageError.new("unknown format #{format.inspect}") end end |