Class: Smoke::Origin

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

Direct Known Subclasses

CSV, Data, Feed, Join, YQL

Defined Under Namespace

Classes: UnavailableFormat

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, &block) ⇒ Origin

Returns a new instance of Origin.

Raises:

  • (StandardError)


8
9
10
11
12
13
14
15
16
# File 'lib/smoke/origin.rb', line 8

def initialize(name, &block)
  raise StandardError, "Sources must have a name" unless name
  @name = name
  @exposed = true
  @items, @prepare, @requirements, @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

Used to store or retreive variables that are used to query services.

Usage:

Smoke.twitter.username("benschwarz").output

As you can see, the method is chainable, many properties can be set at once, although it may be cleaner to use the method argument method:

Demo:

Smoke.twitter(:username => "benschwarz").output


145
146
147
148
149
150
151
152
153
154
155
# File 'lib/smoke/origin.rb', line 145

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

#exposedObject (readonly)

Returns the value of attribute exposed.



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

def exposed
  @exposed
end

#itemsObject

Returns the value of attribute items.



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

def items
  @items
end

#nameObject

Returns the value of attribute name.



6
7
8
# File 'lib/smoke/origin.rb', line 6

def name
  @name
end

#requirementsObject (readonly)

Returns the value of attribute requirements.



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

def requirements
  @requirements
end

Instance Method Details

#concealObject



240
# File 'lib/smoke/origin.rb', line 240

def conceal; @exposed = false; end

#concealed?Boolean

Returns:

  • (Boolean)


242
# File 'lib/smoke/origin.rb', line 242

def concealed?; !@exposed; end

#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.



206
207
208
# File 'lib/smoke/origin.rb', line 206

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)


70
71
72
73
# File 'lib/smoke/origin.rb', line 70

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

#exposeObject

Expose and conceal, this is stictly a feature of rack/smoke. concealed sources will not be “available” Simply marking off sources, more than anything else



239
# File 'lib/smoke/origin.rb', line 239

def expose; @exposed = true; end

#exposed?Boolean

Returns:

  • (Boolean)


241
# File 'lib/smoke/origin.rb', line 241

def exposed?; @exposed; 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”



107
108
109
110
111
# File 'lib/smoke/origin.rb', line 107

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.



192
193
194
# File 'lib/smoke/origin.rb', line 192

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, :xml and :yaml currently) Ruby is the default format and will automagically yielded from your source

Usage

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


25
26
27
28
29
30
31
32
# File 'lib/smoke/origin.rb', line 25

def output(type = :ruby)
  prepare!
  dispatch if respond_to? :dispatch
  
  Transformer.for(type).generate(name, items)
rescue Registry::NotRegistered => e
  raise UnavailableFormat, e.message
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.



60
61
62
# File 'lib/smoke/origin.rb', line 60

def path(*path)
  @path = path
end

#prepare(args = {}, &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)


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

def prepare(args = {}, &block)
  @requirements = [args.delete(:require)].flatten
  
  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.



218
219
220
# File 'lib/smoke/origin.rb', line 218

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.



178
179
180
# File 'lib/smoke/origin.rb', line 178

def reverse
  @items.reverse!
end

#sort(key) ⇒ Object

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



159
160
161
162
163
# File 'lib/smoke/origin.rb', line 159

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)


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

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(:cameras) do
  ...
  truncate(3)
end
Smoke.cameras.output
=> [{title => "Canon"}, {:title => "Nikon"}, {:title => "Pentax"}]

Truncate must be used inside an ‘emit` block.



232
233
234
# File 'lib/smoke/origin.rb', line 232

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