benschwarz-smoke 0.4.1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +3 -0
- data/VERSION.yml +2 -2
- data/lib/smoke/cache.rb +44 -0
- data/lib/smoke/request.rb +13 -10
- data/lib/smoke/source/yql.rb +1 -0
- data/lib/smoke.rb +11 -5
- data/spec/smoke/cache_spec.rb +53 -0
- data/spec/smoke/{source/shared_spec.rb → shared_spec.rb} +1 -1
- data/spec/smoke/source/yql_spec.rb +24 -0
- data/spec/smoke_spec.rb +3 -3
- data/spec/supports/amc_pacer.json.yql +10 -0
- metadata +7 -4
data/README.markdown
CHANGED
@@ -4,6 +4,9 @@ smoke is a Ruby based DSL that allows you to take data from YQL, RSS / Atom (and
|
|
4
4
|
This "data" can then be re-represented, sorted and filtered. You can collect data from a multiude of sources, sort them on a common property
|
5
5
|
and return a plain old ruby object or json (You could add in something to output XML too)
|
6
6
|
|
7
|
+
## Examples of use
|
8
|
+
I powered [my entire site](http://www.germanforblack.com) [using smoke](http://github.com/benschwarz/benschwarz-site/blob/44de70463c744d821d3ffd2cf940e6d3e415fbdd/lib/stream.rb), until further documentation exists, this is probably a good place to start.
|
9
|
+
|
7
10
|
## Media
|
8
11
|
|
9
12
|
* [Presentation from Melbourne #roro](http://www.slideshare.net/benschwarz/smoke-1371124)
|
data/VERSION.yml
CHANGED
data/lib/smoke/cache.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'moneta'
|
2
|
+
require 'digest/md5'
|
3
|
+
|
4
|
+
module Smoke
|
5
|
+
class Cache
|
6
|
+
class << self
|
7
|
+
def configure!
|
8
|
+
require "moneta/#{Smoke.config[:cache][:store].to_s}" if enabled?
|
9
|
+
rescue LoadError
|
10
|
+
Smoke.log.fatal "Cache store not found. Smoke uses moneta for cache stores, ensure that you've chosen a moneta supported store"
|
11
|
+
end
|
12
|
+
|
13
|
+
def fetch(name, &block)
|
14
|
+
key = generate_key(name)
|
15
|
+
output = (enabled?) ? cache[key] : block.call
|
16
|
+
if output
|
17
|
+
return output
|
18
|
+
else
|
19
|
+
output = block.call
|
20
|
+
persist(key, output)
|
21
|
+
end
|
22
|
+
|
23
|
+
return output
|
24
|
+
end
|
25
|
+
|
26
|
+
def enabled?
|
27
|
+
Smoke.config[:cache][:enabled]
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
def cache
|
32
|
+
Moneta.const_get(Smoke.config[:cache][:store]).send(:new, Smoke.config[:cache][:options])
|
33
|
+
end
|
34
|
+
|
35
|
+
def persist(key, store)
|
36
|
+
cache.store(key, store, :expire_in => Smoke.config[:config][:cache][:expiry])
|
37
|
+
end
|
38
|
+
|
39
|
+
def generate_key(key)
|
40
|
+
Digest::MD5.hexdigest(key)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/smoke/request.rb
CHANGED
@@ -10,6 +10,11 @@ module Smoke
|
|
10
10
|
end
|
11
11
|
|
12
12
|
SUPPORTED_TYPES = %w(json xml javascript)
|
13
|
+
@@request_options = {
|
14
|
+
:user_agent => Smoke.config[:user_agent],
|
15
|
+
:accept_encoding => "gzip"
|
16
|
+
}
|
17
|
+
|
13
18
|
attr_reader :uri, :content_type, :body, :type
|
14
19
|
|
15
20
|
def initialize(uri, options = {})
|
@@ -18,16 +23,14 @@ module Smoke
|
|
18
23
|
end
|
19
24
|
|
20
25
|
private
|
21
|
-
def dispatch
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
@body = request
|
30
|
-
}.join
|
26
|
+
def dispatch
|
27
|
+
Smoke::Cache.fetch @uri do
|
28
|
+
Thread.new {
|
29
|
+
request = RestClient.get(@uri, @@request_options)
|
30
|
+
@content_type = request.headers[:content_type]
|
31
|
+
@body = request
|
32
|
+
}.join
|
33
|
+
end
|
31
34
|
|
32
35
|
present! unless @options[:raw_response]
|
33
36
|
|
data/lib/smoke/source/yql.rb
CHANGED
data/lib/smoke.rb
CHANGED
@@ -9,15 +9,20 @@ module Smoke
|
|
9
9
|
@@active_sources = {}
|
10
10
|
@@config = {
|
11
11
|
:enable_logging => true,
|
12
|
-
:user_agent => "Ruby/#{RUBY_VERSION}/Smoke"
|
12
|
+
:user_agent => "Ruby/#{RUBY_VERSION}/Smoke",
|
13
|
+
:cache => {
|
14
|
+
:enabled => false,
|
15
|
+
:store => :memory,
|
16
|
+
:options => {},
|
17
|
+
:expiry => 1800
|
18
|
+
}
|
13
19
|
}
|
14
20
|
|
15
21
|
# Access registered smoke source instances
|
16
22
|
#
|
17
|
-
#
|
18
|
-
#
|
23
|
+
# Define your source:
|
19
24
|
# Smoke.yql(:ruby) do ....
|
20
|
-
#
|
25
|
+
# Then access it:
|
21
26
|
# Smoke[:ruby]
|
22
27
|
# => #<Smoke::Source::YQL::0x18428d4...
|
23
28
|
def [](source)
|
@@ -66,6 +71,7 @@ module Smoke
|
|
66
71
|
#
|
67
72
|
def configure(&block)
|
68
73
|
yield @@config
|
74
|
+
Smoke::Cache.configure!
|
69
75
|
end
|
70
76
|
|
71
77
|
# Access configuration options
|
@@ -90,7 +96,7 @@ module Smoke
|
|
90
96
|
end
|
91
97
|
end
|
92
98
|
|
93
|
-
%w(core_ext/hash smoke/request smoke/origin).each {|r| require File.join(File.dirname(__FILE__), r)}
|
99
|
+
%w(core_ext/hash smoke/cache smoke/request smoke/origin).each {|r| require File.join(File.dirname(__FILE__), r)}
|
94
100
|
|
95
101
|
class Object # :nodoc:
|
96
102
|
include Smoke
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "..", "spec_helper.rb")
|
2
|
+
|
3
|
+
describe Smoke::Cache do
|
4
|
+
describe "class methods" do
|
5
|
+
it "should respond to configure!" do
|
6
|
+
Smoke::Cache.should respond_to(:configure!)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should respond to fetch" do
|
10
|
+
Smoke::Cache.should respond_to(:fetch)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should responsd to enabled?" do
|
14
|
+
Smoke::Cache.should respond_to(:enabled?)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "configuration" do
|
19
|
+
it "should not be enabled (by default)" do
|
20
|
+
Smoke::Cache.should_not be_enabled
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be enabled" do
|
24
|
+
Smoke.configure {|c| c[:cache][:enabled] = true }
|
25
|
+
Smoke::Cache.should be_enabled
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should not be enabled" do
|
29
|
+
Smoke.configure {|c| c[:cache][:enabled] = false }
|
30
|
+
Smoke::Cache.should_not be_enabled
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "invalid configuration" do
|
34
|
+
before do
|
35
|
+
@kernel = mock(Kernel)
|
36
|
+
@kernel.stub!(:exit)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should log with bad configuration" do
|
40
|
+
Proc.new {
|
41
|
+
Smoke.should_receive(:log)
|
42
|
+
Smoke.configure {|c| c[:cache][:store] = :ponies }
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "caching my block" do
|
49
|
+
before :all do
|
50
|
+
Smoke.configure {|c| c[:cache][:store] = :memory }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -26,6 +26,30 @@ describe "YQL" do
|
|
26
26
|
Smoke[:search].items.should be_an_instance_of(Array)
|
27
27
|
end
|
28
28
|
|
29
|
+
describe "select" do
|
30
|
+
before do
|
31
|
+
FakeWeb.register_uri("http://query.yahooapis.com:80/v1/public/yql?q=SELECT%20url%20FROM%20search.images%20WHERE%20query%20=%20'amc%20pacer'&format=json", :response => File.join(SPEC_DIR, 'supports', 'amc_pacer.json.yql'))
|
32
|
+
|
33
|
+
Smoke.yql(:pacer) do
|
34
|
+
select :url
|
35
|
+
from "search.images"
|
36
|
+
where :query, "amc pacer"
|
37
|
+
|
38
|
+
path :query, :results, :result
|
39
|
+
end
|
40
|
+
|
41
|
+
Smoke[:pacer].output
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should query correctly" do
|
45
|
+
Smoke[:pacer].request.uri.should == "http://query.yahooapis.com/v1/public/yql?q=SELECT%20url%20FROM%20search.images%20WHERE%20query%20=%20'amc%20pacer'&format=json"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should have urls" do
|
49
|
+
Smoke[:pacer].output.first.should have_key(:url)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
29
53
|
describe "after dispatch" do
|
30
54
|
before do
|
31
55
|
Smoke[:search].output
|
data/spec/smoke_spec.rb
CHANGED
@@ -42,9 +42,9 @@ describe Smoke do
|
|
42
42
|
end
|
43
43
|
|
44
44
|
it "should allow overwriting default configurations" do
|
45
|
-
key =
|
46
|
-
Smoke.configure {|c| c[key] =
|
47
|
-
Smoke.config[key].should
|
45
|
+
key = :user_agent
|
46
|
+
Smoke.configure {|c| c[key] = "Smoke, dude" }
|
47
|
+
Smoke.config[key].should == "Smoke, dude"
|
48
48
|
end
|
49
49
|
end
|
50
50
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Date: Mon, 10 Aug 2009 01:32:37 GMT
|
3
|
+
P3P: policyref="http://info.yahoo.com/w3c/p3p.xml", CP="CAO DSP COR CUR ADM DEV TAI PSA PSD IVAi IVDi CONi TELo OTPi OUR DELi SAMi OTRi UNRi PUBi IND PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA POL HEA PRE LOC GOV"
|
4
|
+
Access-Control-Allow-Origin: *
|
5
|
+
Cache-Control: no-cache, private
|
6
|
+
Content-Length: 1193
|
7
|
+
Connection: close
|
8
|
+
Content-Type: application/json;charset=utf-8
|
9
|
+
|
10
|
+
{"query":{"count":"10","created":"2009-08-10T01:32:37Z","lang":"en-US","updated":"2009-08-10T01:32:37Z","uri":"http://query.yahooapis.com/v1/yql?q=SELECT+url+FROM+search.images+WHERE+query+%3D+%27amc+pacer%27","diagnostics":{"publiclyCallable":"true","url":{"execution-time":"222","content":"http://boss.yahooapis.com/ysearch/images/v1/amc%20pacer?format=xml&start=0&count=10"},"user-time":"225","service-time":"222","build-version":"2579"},"results":{"result":[{"url":"http://www.carrera.no/images/AMC_Pacer_01.jpg"},{"url":"http://static.flickr.com/116/308140444_549b19d604.jpg"},{"url":"http://static.flickr.com/2132/2594281582_9ea9829b46.jpg"},{"url":"http://brennerworld.blogware.com/BlogEntries/BurgerPacer.jpg"},{"url":"http://www.stationwagon.com/gallery/pictures/19xx_AMC_Pacer_limo.jpg"},{"url":"http://www.stationwagon.com/gallery/pictures/1978_AMC_Pacer.jpg"},{"url":"http://www.shorey.net/Auto/American/AMC/1975%20AMC%20Pacer_2.jpg"},{"url":"http://www.allsportauto.com/photoautre5/amc/pacer/1976_amc_pacer_15_m.jpg"},{"url":"http://www.productioncars.com/send_file.php/amc_pacer_wagon_1980.jpg"},{"url":"http://www.productioncars.com/send_file.php/amc_pacer_maroon_1975.jpg"}]}}}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: benschwarz-smoke
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Schwarz
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-08-
|
12
|
+
date: 2009-08-10 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -57,6 +57,7 @@ files:
|
|
57
57
|
- lib/core_ext
|
58
58
|
- lib/core_ext/hash.rb
|
59
59
|
- lib/smoke
|
60
|
+
- lib/smoke/cache.rb
|
60
61
|
- lib/smoke/origin.rb
|
61
62
|
- lib/smoke/request.rb
|
62
63
|
- lib/smoke/source
|
@@ -68,18 +69,20 @@ files:
|
|
68
69
|
- spec/core_ext
|
69
70
|
- spec/core_ext/hash_spec.rb
|
70
71
|
- spec/smoke
|
72
|
+
- spec/smoke/cache_spec.rb
|
71
73
|
- spec/smoke/origin_spec.rb
|
72
74
|
- spec/smoke/request_spec.rb
|
75
|
+
- spec/smoke/shared_spec.rb
|
73
76
|
- spec/smoke/source
|
74
77
|
- spec/smoke/source/data_spec.rb
|
75
78
|
- spec/smoke/source/feed_spec.rb
|
76
79
|
- spec/smoke/source/join_spec.rb
|
77
|
-
- spec/smoke/source/shared_spec.rb
|
78
80
|
- spec/smoke/source/yql_spec.rb
|
79
81
|
- spec/smoke_spec.rb
|
80
82
|
- spec/spec.opts
|
81
83
|
- spec/spec_helper.rb
|
82
84
|
- spec/supports
|
85
|
+
- spec/supports/amc_pacer.json.yql
|
83
86
|
- spec/supports/datatables.yql
|
84
87
|
- spec/supports/flickr-photo.json
|
85
88
|
- spec/supports/gzip_response.txt
|
@@ -88,7 +91,7 @@ files:
|
|
88
91
|
- spec/supports/slashdot.xml
|
89
92
|
- spec/supports/test_source.rb
|
90
93
|
- LICENSE
|
91
|
-
has_rdoc:
|
94
|
+
has_rdoc: false
|
92
95
|
homepage: http://github.com/benschwarz/smoke
|
93
96
|
licenses:
|
94
97
|
post_install_message:
|