snoop 0.8.5 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +3 -0
- data/lib/snoop.rb +1 -0
- data/lib/snoop/http.rb +1 -28
- data/lib/snoop/notifier.rb +37 -0
- data/lib/snoop/version.rb +1 -1
- data/snoop.gemspec +1 -0
- data/spec/acceptance/http_spec.rb +2 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/unit/http_spec.rb +2 -95
- data/spec/unit/notifier_spec.rb +107 -0
- metadata +21 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fa3e46c444207c14e901618fd4dcebda2d071a6d
|
4
|
+
data.tar.gz: c618dcb9b9ee2df1e0132160b9e29271e3d36cf5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a9c16933727dce0b5f51136766655b05879f7b6788d55b785f890574ef9863fd57690a84317565d0124c6002eac7ff93f65caf61478515ac140151d7eb17aa9
|
7
|
+
data.tar.gz: f353f036f82730ca2969d0b4c1fd8dd0d72ea6d69b6dd0ce0a6ede4edeac576a76b7f78d61b2e9fe620157d76f4469ed0a3173158f2f247e4f5b1883dcdf261e
|
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Snoop
|
2
2
|
[](https://travis-ci.org/chrishunt/snoop)
|
3
|
+
[](https://coveralls.io/r/chrishunt/snoop)
|
3
4
|
[](https://codeclimate.com/github/chrishunt/snoop)
|
4
5
|
|
5
6
|
Snoop on content, be notified when it changes.
|
@@ -134,6 +135,8 @@ print our new follower count to the terminal. When we've reached 500 followers,
|
|
134
135
|
the `Snoop` will stop checking.
|
135
136
|
|
136
137
|
```ruby
|
138
|
+
require 'snoop'
|
139
|
+
|
137
140
|
snoop = Snoop::Http.new(
|
138
141
|
url: 'https://twitter.com/chrishunt',
|
139
142
|
css: '[data-element-term="follower_stats"]'
|
data/lib/snoop.rb
CHANGED
data/lib/snoop/http.rb
CHANGED
@@ -2,7 +2,7 @@ require 'httparty'
|
|
2
2
|
require 'nokogiri'
|
3
3
|
|
4
4
|
module Snoop
|
5
|
-
class Http
|
5
|
+
class Http < Notifier
|
6
6
|
UrlRequiredException = Class.new(StandardError)
|
7
7
|
|
8
8
|
DEFAULT_INIT_OPTIONS = {
|
@@ -11,15 +11,7 @@ module Snoop
|
|
11
11
|
http_client: HTTParty
|
12
12
|
}
|
13
13
|
|
14
|
-
DEFAULT_NOTIFY_OPTIONS = {
|
15
|
-
delay: 0,
|
16
|
-
count: 1,
|
17
|
-
while: -> { false },
|
18
|
-
until: -> { true }
|
19
|
-
}
|
20
|
-
|
21
14
|
attr_reader :url, :css, :http_client
|
22
|
-
attr_accessor :content
|
23
15
|
|
24
16
|
def initialize(options = {})
|
25
17
|
options = DEFAULT_INIT_OPTIONS.merge options
|
@@ -31,25 +23,6 @@ module Snoop
|
|
31
23
|
@http_client = options.fetch :http_client
|
32
24
|
end
|
33
25
|
|
34
|
-
def notify(options = {})
|
35
|
-
options = DEFAULT_NOTIFY_OPTIONS.merge options
|
36
|
-
|
37
|
-
while (
|
38
|
-
(options[:count] -= 1) >= 0 ||
|
39
|
-
options.fetch(:while).call ||
|
40
|
-
!options.fetch(:until).call
|
41
|
-
)
|
42
|
-
yield content if content_changed?
|
43
|
-
sleep options.fetch(:delay)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def content_changed?
|
48
|
-
old_content = @content
|
49
|
-
@content = fetch_content
|
50
|
-
old_content != @content
|
51
|
-
end
|
52
|
-
|
53
26
|
def fetch_content
|
54
27
|
content = http_client.get(url).body
|
55
28
|
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Snoop
|
2
|
+
class Notifier
|
3
|
+
UnimplementedException = Class.new(StandardError)
|
4
|
+
|
5
|
+
attr_accessor :content
|
6
|
+
|
7
|
+
DEFAULT_NOTIFY_OPTIONS = {
|
8
|
+
delay: 0,
|
9
|
+
count: 1,
|
10
|
+
while: -> { false },
|
11
|
+
until: -> { true }
|
12
|
+
}
|
13
|
+
|
14
|
+
def notify(options = {})
|
15
|
+
options = DEFAULT_NOTIFY_OPTIONS.merge options
|
16
|
+
|
17
|
+
while (
|
18
|
+
(options[:count] -= 1) >= 0 ||
|
19
|
+
options.fetch(:while).call ||
|
20
|
+
!options.fetch(:until).call
|
21
|
+
)
|
22
|
+
yield content if content_changed?
|
23
|
+
sleep options.fetch(:delay)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def content_changed?
|
28
|
+
old_content = @content
|
29
|
+
@content = fetch_content
|
30
|
+
old_content != @content
|
31
|
+
end
|
32
|
+
|
33
|
+
def fetch_content
|
34
|
+
raise UnimplementedException.new '#fetch_content must be implemented'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/snoop/version.rb
CHANGED
data/snoop.gemspec
CHANGED
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency 'bundler', '~> 1.3'
|
22
22
|
spec.add_development_dependency 'rake'
|
23
23
|
spec.add_development_dependency 'rspec'
|
24
|
+
spec.add_development_dependency 'coveralls'
|
24
25
|
spec.add_development_dependency 'thin'
|
25
26
|
spec.add_development_dependency 'sinatra'
|
26
27
|
|
data/spec/spec_helper.rb
ADDED
data/spec/unit/http_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'snoop/notifier'
|
1
3
|
require 'snoop/http'
|
2
4
|
|
3
5
|
describe Snoop::Http do
|
@@ -30,101 +32,6 @@ describe Snoop::Http do
|
|
30
32
|
end
|
31
33
|
end
|
32
34
|
|
33
|
-
describe '#notify' do
|
34
|
-
let(:content) { 'abc123' }
|
35
|
-
let(:content_changed?) { true }
|
36
|
-
|
37
|
-
before do
|
38
|
-
subject.stub(
|
39
|
-
content: content,
|
40
|
-
content_changed?: content_changed?
|
41
|
-
)
|
42
|
-
end
|
43
|
-
|
44
|
-
it 'notifies the requested number of times' do
|
45
|
-
notification_count = 0
|
46
|
-
|
47
|
-
subject.notify count: 5 do
|
48
|
-
notification_count += 1
|
49
|
-
end
|
50
|
-
|
51
|
-
expect(notification_count).to eq 5
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'notifies while an expression is true' do
|
55
|
-
notification_count = 0
|
56
|
-
|
57
|
-
subject.notify while: -> { notification_count < 3 } do
|
58
|
-
notification_count += 1
|
59
|
-
end
|
60
|
-
|
61
|
-
expect(notification_count).to eq 3
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'notifies until an expression is true' do
|
65
|
-
notification_count = 0
|
66
|
-
|
67
|
-
subject.notify until: -> { notification_count > 2 } do
|
68
|
-
notification_count += 1
|
69
|
-
end
|
70
|
-
|
71
|
-
expect(notification_count).to eq 3
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'yields the content to the notification block' do
|
75
|
-
yielded_content = nil
|
76
|
-
|
77
|
-
subject.notify { |content| yielded_content = content }
|
78
|
-
|
79
|
-
expect(yielded_content).to eq content
|
80
|
-
end
|
81
|
-
|
82
|
-
context 'when the content does not change' do
|
83
|
-
let(:content_changed?) { false }
|
84
|
-
|
85
|
-
it 'does not yield the notification block' do
|
86
|
-
yielded = false
|
87
|
-
|
88
|
-
subject.notify { yielded = true }
|
89
|
-
|
90
|
-
expect(yielded).to be_false
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
describe '#content_changed?' do
|
96
|
-
it 'updates the content' do
|
97
|
-
subject.content = 'abc123'
|
98
|
-
subject.stub(fetch_content: 'def456')
|
99
|
-
|
100
|
-
subject.content_changed?
|
101
|
-
|
102
|
-
expect(subject.content).to eq 'def456'
|
103
|
-
end
|
104
|
-
|
105
|
-
context 'when content has changed' do
|
106
|
-
before do
|
107
|
-
subject.content = 'abc123'
|
108
|
-
subject.stub(fetch_content: 'def456')
|
109
|
-
end
|
110
|
-
|
111
|
-
it 'returns true' do
|
112
|
-
expect(subject.content_changed?).to be_true
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
context 'when content has not changed' do
|
117
|
-
before do
|
118
|
-
subject.content = 'abc123'
|
119
|
-
subject.stub(fetch_content: 'abc123')
|
120
|
-
end
|
121
|
-
|
122
|
-
it 'returns false' do
|
123
|
-
expect(subject.content_changed?).to be_false
|
124
|
-
end
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
35
|
describe '#fetch_content' do
|
129
36
|
before do
|
130
37
|
response = stub('HttpResponse', body: body)
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'snoop/notifier'
|
3
|
+
|
4
|
+
describe Snoop::Notifier do
|
5
|
+
describe '#fetch_content' do
|
6
|
+
it 'raises an exception for unimplemented required methods' do
|
7
|
+
expect {
|
8
|
+
subject.fetch_content
|
9
|
+
}.to raise_error Snoop::Notifier::UnimplementedException
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#notify' do
|
14
|
+
let(:content) { 'abc123' }
|
15
|
+
let(:content_changed?) { true }
|
16
|
+
|
17
|
+
before do
|
18
|
+
subject.stub(
|
19
|
+
content: content,
|
20
|
+
content_changed?: content_changed?
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'notifies the requested number of times' do
|
25
|
+
notification_count = 0
|
26
|
+
|
27
|
+
subject.notify count: 5 do
|
28
|
+
notification_count += 1
|
29
|
+
end
|
30
|
+
|
31
|
+
expect(notification_count).to eq 5
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'notifies while an expression is true' do
|
35
|
+
notification_count = 0
|
36
|
+
|
37
|
+
subject.notify while: -> { notification_count < 3 } do
|
38
|
+
notification_count += 1
|
39
|
+
end
|
40
|
+
|
41
|
+
expect(notification_count).to eq 3
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'notifies until an expression is true' do
|
45
|
+
notification_count = 0
|
46
|
+
|
47
|
+
subject.notify until: -> { notification_count > 2 } do
|
48
|
+
notification_count += 1
|
49
|
+
end
|
50
|
+
|
51
|
+
expect(notification_count).to eq 3
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'yields the content to the notification block' do
|
55
|
+
yielded_content = nil
|
56
|
+
|
57
|
+
subject.notify { |content| yielded_content = content }
|
58
|
+
|
59
|
+
expect(yielded_content).to eq content
|
60
|
+
end
|
61
|
+
|
62
|
+
context 'when the content does not change' do
|
63
|
+
let(:content_changed?) { false }
|
64
|
+
|
65
|
+
it 'does not yield the notification block' do
|
66
|
+
yielded = false
|
67
|
+
|
68
|
+
subject.notify { yielded = true }
|
69
|
+
|
70
|
+
expect(yielded).to be_false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#content_changed?' do
|
76
|
+
it 'updates the content' do
|
77
|
+
subject.content = 'abc123'
|
78
|
+
subject.stub(fetch_content: 'def456')
|
79
|
+
|
80
|
+
subject.content_changed?
|
81
|
+
|
82
|
+
expect(subject.content).to eq 'def456'
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'when content has changed' do
|
86
|
+
before do
|
87
|
+
subject.content = 'abc123'
|
88
|
+
subject.stub(fetch_content: 'def456')
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'returns true' do
|
92
|
+
expect(subject.content_changed?).to be_true
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when content has not changed' do
|
97
|
+
before do
|
98
|
+
subject.content = 'abc123'
|
99
|
+
subject.stub(fetch_content: 'abc123')
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'returns false' do
|
103
|
+
expect(subject.content_changed?).to be_false
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: snoop
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Hunt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-04-
|
11
|
+
date: 2013-04-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - '>='
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: coveralls
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: thin
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -124,11 +138,14 @@ files:
|
|
124
138
|
- Rakefile
|
125
139
|
- lib/snoop.rb
|
126
140
|
- lib/snoop/http.rb
|
141
|
+
- lib/snoop/notifier.rb
|
127
142
|
- lib/snoop/version.rb
|
128
143
|
- snoop.gemspec
|
129
144
|
- spec/acceptance/http_spec.rb
|
145
|
+
- spec/spec_helper.rb
|
130
146
|
- spec/support/http_server.rb
|
131
147
|
- spec/unit/http_spec.rb
|
148
|
+
- spec/unit/notifier_spec.rb
|
132
149
|
homepage: https://github.com/chrishunt/snoop
|
133
150
|
licenses:
|
134
151
|
- MIT
|
@@ -155,5 +172,7 @@ specification_version: 4
|
|
155
172
|
summary: Snoop on content, be notified when it changes.
|
156
173
|
test_files:
|
157
174
|
- spec/acceptance/http_spec.rb
|
175
|
+
- spec/spec_helper.rb
|
158
176
|
- spec/support/http_server.rb
|
159
177
|
- spec/unit/http_spec.rb
|
178
|
+
- spec/unit/notifier_spec.rb
|