Class: Feedx::Producer

Inherits:
Object
  • Object
show all
Defined in:
lib/feedx/producer.rb

Overview

Produces a relation as an encoded feed to a remote location.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url, last_modified: nil, format_options: {}, enum: nil, **opts) { ... } ⇒ Producer

Returns a new instance of Producer.

Parameters:

  • url (String)

    the destination URL.

  • opts (Hash)

    options

Options Hash (**opts):

  • :enum (Enumerable, ActiveRecord::Relation)

    relation or enumerator to stream.

  • :format (Symbol, Class<Feedx::Format::Abstract>)

    custom formatter. Default: from file extension.

  • :compress (Symbol, Class<Feedx::Compression::Abstract>)

    enable compression. Default: from file extension.

  • :last_modified (Time, Proc)

    the last modified time, used to determine if a push is necessary.

Yields:

  • A block factory to generate the relation or enumerator.

Yield Returns:

  • (Enumerable, ActiveRecord::Relation)

    the relation or enumerator to stream.

Raises:

  • (ArgumentError)


21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/feedx/producer.rb', line 21

def initialize(url, last_modified: nil, format_options: {}, enum: nil, **opts, &block)
  @enum = enum || block
  raise ArgumentError, "#{self.class.name}.new expects an :enum option or a block factory" unless @enum

  @url  = url
  @opts = opts.merge(format_options)
  @last_mod = last_modified

  return if format_options.empty? || (defined?(Gem::Deprecate) && Gem::Deprecate.skip)

  warn "WARNING: passing format_options is deprecated; pass the options inline instead (called from #{caller(2..2).first})."
end

Class Method Details

.perform(url, **opts, &block) ⇒ Object

See constructor.



9
10
11
# File 'lib/feedx/producer.rb', line 9

def self.perform(url, **opts, &block)
  new(url, **opts, &block).perform
end

Instance Method Details

#performObject



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/feedx/producer.rb', line 34

def perform
  Feedx::Stream.open(@url, **@opts) do |stream|
    enum = @enum.is_a?(Proc) ? @enum.call : @enum
    last_mod = @last_mod.is_a?(Proc) ? @last_mod.call(enum) : @last_mod
    local_rev = last_mod.is_a?(Integer) ? last_mod : (last_mod.to_f * 1000).floor

    begin
         = stream.blob.info.
      remote_rev = ([META_LAST_MODIFIED] || [META_LAST_MODIFIED_DC]).to_i
      return -1 unless local_rev > remote_rev
    rescue BFS::FileNotFound
      nil
    end if local_rev.positive?

    stream.create metadata: { META_LAST_MODIFIED => local_rev.to_s } do |fmt|
      iter = enum.respond_to?(:find_each) ? :find_each : :each
      enum.send(iter) {|rec| fmt.encode(rec, **@opts) }
    end
    stream.blob.info.size
  end
end