Class: Smoke::Origin

Inherits:
Object show all
Defined in:
lib/smoke/origin.rb

Direct Known Subclasses

Source::Data, Source::Feed, Source::Join, Source::YQL

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, &block) ⇒ Origin

Returns a new instance of Origin.

Raises:

  • (StandardError)


6
7
8
9
10
11
12
13
# File 'lib/smoke/origin.rb', line 6

def initialize(name, &block)
  raise StandardError, "Sources must have a name" unless name
  @name = name
  @items, @prepare, @transformation = [], [], []

  activate!
  instance_eval(&block) if block_given?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *args, &block) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
# File 'lib/smoke/origin.rb', line 135

def method_missing(symbol, *args, &block)
  ivar = "@#{symbol}"
  
  if args.empty?
    return instance_variable_get(ivar) || super  
  else
    instance_variable_set(ivar, args.pop)
  end

  return self
end

Instance Attribute Details

#itemsObject

Returns the value of attribute items.



3
4
5
# File 'lib/smoke/origin.rb', line 3

def items
  @items
end

#nameObject

Returns the value of attribute name.



4
5
6
# File 'lib/smoke/origin.rb', line 4

def name
  @name
end

Instance Method Details

#discard(key, matcher) ⇒ Object

Discard items that do not match the regex

Usage (block, during initialization):

Smoke.yql(:ruby) do
  ...
  emit do
    discard(:title, /tuesday/i)
  end
end

Discard must be used inside an ‘emit` block.



196
197
198
# File 'lib/smoke/origin.rb', line 196

def discard(key, matcher)
  @items.reject! {|i| (i[key] =~ matcher) ? true : false }
end

#emit(&block) ⇒ Object

Transform each item

Usage:

emit do
  rename(:href => :link)
end

Raises:

  • (ArgumentError)


72
73
74
75
# File 'lib/smoke/origin.rb', line 72

def emit(&block)
  raise ArgumentError, "requires a block" unless block_given?
  @transformation << block
end

#insert(key, value) ⇒ Object

Insert must be used inside an ‘emit` block. It can be used to insert named keys to all items within the result set

Usage:

emit do
  insert :source, "twitter"
end

Once output is called, all items will contain a key of :source with a value of “twitter”



109
110
111
112
113
# File 'lib/smoke/origin.rb', line 109

def insert(key, value)
  @items.each do |item|
    item[key] = value
  end
end

#keep(key, matcher) ⇒ Object

Keep items that match the regex

Usage (block, during initialization):

Smoke.yql(:ruby) do
  ...
  emit do
    keep(:title, /tuesday/i)
  end
end

Keep must be used inside an ‘emit` block.



182
183
184
# File 'lib/smoke/origin.rb', line 182

def keep(key, matcher)
  @items.reject! {|i| (i[key] =~ matcher) ? false : true }
end

#output(type = :ruby) ⇒ Object

Output your items in a range of formats (:ruby, :json and :yaml currently) Ruby is the default format and will automagically yielded from your source

Usage

output(:json)
=> "[{title: \"Ray\"}, {title: \"Peace\"}]"


22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/smoke/origin.rb', line 22

def output(type = :ruby)
  prepare!
  dispatch if respond_to? :dispatch
  
  case type
  when :json
    return ::JSON.generate(@items)
  when :yaml
    return YAML.dump(@items)
  else
    return @items
  end      
end

#path(*path) ⇒ Object

Path allows you to traverse the tree of a the items returned to only give you access to what you’re interested in.

Usage: path :down, :to, :the, :data

Will traverse through a tree as follows:

{
  :down => {
    :to => {
      :the => {
        :data => []
      }
    }
  }
}

You will need to help smoke find an array of items that you’re interested in.



62
63
64
# File 'lib/smoke/origin.rb', line 62

def path(*path)
  @path = path
end

#prepare(&block) ⇒ Object

Prepare is used when you’d like to provision for arguments / variables to be set after the source definition. Eg, create a source definition for twitter, omitting the “username”. Set the username using chaining later.

Usage:

# Definition
Smoke.feed :twitter do
  prepare do
    url "http://twitter.com/#{username}/rss"
  end
end

# End use
Smoke[:twitter].username(:benschwarz).output

Raises:

  • (ArgumentError)


130
131
132
133
# File 'lib/smoke/origin.rb', line 130

def prepare(&block)
  raise ArgumentError, "requires a block" unless block_given?
  @prepare << block
end

#rename(*args) ⇒ Object

Rename one or many keys at a time

Usage

# Renames all items with a key of href to link
rename(:href => :link)

or

rename(:href => :link, :description => :excerpt)

Rename must be used inside an ‘emit` block.



208
209
210
# File 'lib/smoke/origin.rb', line 208

def rename(*args)
  @items.each {|item| item.rename(*args) }
end

#reverseObject

Reverse the order of the items

Usage

Smoke[:ruby].output

Returns [=> “Platypus”, => “Kangaroo”]

Smoke.yql(:ruby) do
  ... Define your source
  emit do
    reverse
  end
end

Returns [=> “Kangaroo”, => “Platypus”] Reverse must be used inside an ‘emit` block.



168
169
170
# File 'lib/smoke/origin.rb', line 168

def reverse
  @items.reverse!
end

#sort(key) ⇒ Object

Re-sort items by a particular key Sort must be used inside an ‘emit` block.



149
150
151
152
153
# File 'lib/smoke/origin.rb', line 149

def sort(key)
  @items = @items.sort_by{|i| i[key] }
rescue NoMethodError => e
  Smoke.log.info "You're trying to sort by \"#{key}\" but it does not exist in your item set"
end

#transform(*keys) ⇒ Object

Transform must be used inside an ‘emit` block. It can be used to alter named keys within the item set

Usage:

emit do
  transform :name, :description do |name|
    name.gsub(/\302/, "")
  end
end

In quasi-english: The result of the block is returned and set to each of the :name and :description keys in the result set.

Raises:

  • (ArgumentError)


89
90
91
92
93
94
95
96
# File 'lib/smoke/origin.rb', line 89

def transform(*keys)
  raise ArgumentError, "requires a block" unless block_given?
  keys.each do |key|
    items.each do |item|
      item[key] = yield(item[key]) || item[key]
    end
  end
end

#truncate(length) ⇒ Object

Truncate your result set to this many objects

Usage

Smoke.yql(:ruby) do
  ...
  truncate(3)
end
Smoke[:ruby].output
=> [{title => "Canon"}, {:title => "Nikon"}, {:title => "Pentax"}]

Truncate must be used inside an ‘emit` block.



222
223
224
# File 'lib/smoke/origin.rb', line 222

def truncate(length)
  @items = @items[0..(length - 1)]
end