gnip-rule 0.1.1
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.
- data/.gitignore +6 -0
- data/.pryrc +2 -0
- data/.rvmrc +1 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE +19 -0
- data/README.md +35 -0
- data/Rakefile +1 -0
- data/gnip-rule.gemspec +27 -0
- data/lib/gnip-rule.rb +7 -0
- data/lib/gnip-rule/client.rb +64 -0
- data/lib/gnip-rule/rule.rb +56 -0
- data/lib/gnip-rule/version.rb +3 -0
- data/spec/gnip-rule/client_spec.rb +66 -0
- data/spec/gnip-rule/rule_spec.rb +57 -0
- data/spec/spec-helper.rb +4 -0
- metadata +124 -0
data/.gitignore
ADDED
data/.pryrc
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use 1.9.3@gnip-rule --create
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2012 Eric Wendelin
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
8
|
+
so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# gnip-rule
|
2
|
+
Ruby library for working with the Gnip Rules API
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
Add the following to your `Gemfile`:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
gem 'gnip-rule', '~> 0.1.1'
|
9
|
+
```
|
10
|
+
|
11
|
+
## Example
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
require 'gnip-rule'
|
15
|
+
|
16
|
+
ruler = GnipRule::Client.new(GNIP_API_URL, GNIP_USERNAME, GNIP_PASSWORD)
|
17
|
+
|
18
|
+
# Add as a String, Rule, or Array of either
|
19
|
+
ruler.add('foo')
|
20
|
+
ruler.add('bar', 'tag')
|
21
|
+
ruler.add(['foo', 'bar', 'baz'], 'tag')
|
22
|
+
ruler.add(GnipRule::Rule.new('value', 'tag'))
|
23
|
+
ruler.add([GnipRule::Rule.new('value', 'tag'), ruler.add(GnipRule::Rule.new('othervalue', 'othertag'))])
|
24
|
+
|
25
|
+
# Same with delete
|
26
|
+
ruler.delete('baz', 'tag')
|
27
|
+
ruler.delete(['foo', 'bar'])
|
28
|
+
ruler.delete(GnipRule::Rule.new('value', 'tag'))
|
29
|
+
|
30
|
+
# Get all ruler as Rule objects
|
31
|
+
ruler.list()
|
32
|
+
```
|
33
|
+
|
34
|
+
## License
|
35
|
+
MIT License: http://www.opensource.org/licenses/mit-license.php
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/gnip-rule.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path('../lib', __FILE__)
|
3
|
+
require 'gnip-rule/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = 'gnip-rule'
|
7
|
+
s.version = GnipRule::VERSION
|
8
|
+
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ['Eric Wendelin']
|
11
|
+
s.email = ['me@eriwen.com']
|
12
|
+
s.homepage = 'https://github.com/eriwen/gnip-rule'
|
13
|
+
s.summary = %q{Ruby library for working with the Gnip Rules API}
|
14
|
+
s.description = s.summary
|
15
|
+
|
16
|
+
s.rubyforge_project = 'gnip-rule'
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ['lib']
|
22
|
+
|
23
|
+
s.add_development_dependency 'rspec'
|
24
|
+
|
25
|
+
s.add_dependency 'curb', '>= 0.8.0', '< 0.9.0'
|
26
|
+
s.add_dependency 'json', '>= 1.6.0', '< 1.7.0'
|
27
|
+
end
|
data/lib/gnip-rule.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'curb'
|
2
|
+
require 'json'
|
3
|
+
require 'gnip-rule/rule'
|
4
|
+
|
5
|
+
module GnipRule
|
6
|
+
class Client
|
7
|
+
|
8
|
+
attr_reader :url, :username, :password
|
9
|
+
|
10
|
+
def initialize(url, username, password)
|
11
|
+
@url = url.gsub(/\.xml$/, '.json')
|
12
|
+
@username = username
|
13
|
+
@password = password
|
14
|
+
end
|
15
|
+
|
16
|
+
def add(value, tag=nil)
|
17
|
+
post(@url, jsonify_rules(value, tag))
|
18
|
+
end
|
19
|
+
|
20
|
+
def delete(value, tag=nil)
|
21
|
+
post("#{@url}?_method=delete", jsonify_rules(value, tag))
|
22
|
+
end
|
23
|
+
|
24
|
+
def list()
|
25
|
+
rules = nil
|
26
|
+
Curl::Easy.http_get(@url) do |curl|
|
27
|
+
curl.http_auth_types = :basic
|
28
|
+
curl.username = @username
|
29
|
+
curl.password = @password
|
30
|
+
curl.on_body do |obj|
|
31
|
+
rules = JSON.parse(obj)['rules'].collect { |o| Rule.new(o['value'], o['tag']) }
|
32
|
+
obj.size
|
33
|
+
end
|
34
|
+
end
|
35
|
+
rules
|
36
|
+
end
|
37
|
+
|
38
|
+
def jsonify_rules(values, tag=nil)
|
39
|
+
rules = nil
|
40
|
+
if values.instance_of?(Array)
|
41
|
+
rules = values.collect { |o| o.instance_of?(Rule) ? o : Rule.new(o, tag) }
|
42
|
+
elsif values.instance_of?(Rule)
|
43
|
+
rules = [values]
|
44
|
+
else
|
45
|
+
rules = [Rule.new(values, tag)]
|
46
|
+
end
|
47
|
+
{:rules => rules.collect(&:as_hash)}.to_json
|
48
|
+
end
|
49
|
+
|
50
|
+
protected
|
51
|
+
def post(url, data)
|
52
|
+
Curl::Easy.http_post(url, data) do |curl|
|
53
|
+
curl.http_auth_types = :basic
|
54
|
+
curl.username = @username
|
55
|
+
curl.password = @password
|
56
|
+
curl.on_complete do |res|
|
57
|
+
if res.response_code >= 400
|
58
|
+
raise "Got #{res.response_code}; body: #{res.body_str}"
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module GnipRule
|
4
|
+
class Rule
|
5
|
+
attr_accessor :value, :tag
|
6
|
+
|
7
|
+
def initialize(value, tag=nil)
|
8
|
+
@value = value
|
9
|
+
@tag = tag
|
10
|
+
end
|
11
|
+
|
12
|
+
def valid?
|
13
|
+
# See http://docs.gnip.com/w/page/35663947/Power%20Track
|
14
|
+
if contains_stop_word?(@value) || too_long?(@value) || contains_negated_or?(@value) || too_many_positive_terms?(@value) || contains_empty_source?(@value)
|
15
|
+
return false
|
16
|
+
end
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def as_json
|
21
|
+
as_hash.to_json
|
22
|
+
end
|
23
|
+
|
24
|
+
def as_hash
|
25
|
+
obj = {:value => @value}
|
26
|
+
obj[:tag] = @tag unless @tag.nil?
|
27
|
+
obj
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_s
|
31
|
+
as_json
|
32
|
+
end
|
33
|
+
|
34
|
+
protected
|
35
|
+
def contains_stop_word?(value)
|
36
|
+
stop_words = %W(a an and at but by com from http https if in is it its me my or rt the this to too via we www you)
|
37
|
+
(stop_words & value.gsub(/\"[^\"]*\"/, '').split(/\s/)).size > 0
|
38
|
+
end
|
39
|
+
|
40
|
+
def too_long?(value)
|
41
|
+
value.size > 1024
|
42
|
+
end
|
43
|
+
|
44
|
+
def contains_negated_or?(value)
|
45
|
+
!value[/\-\w+ OR/].nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
def too_many_positive_terms?(value)
|
49
|
+
value.scan(/\b\w+|\"[\-\s\w]+\"\b/).size > 10
|
50
|
+
end
|
51
|
+
|
52
|
+
def contains_empty_source?(value)
|
53
|
+
!value[/source\:\s/].nil?
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec-helper'
|
2
|
+
|
3
|
+
require 'gnip-rule/client'
|
4
|
+
|
5
|
+
describe GnipRule::Client do
|
6
|
+
let(:fake_curb) { double("Curl::Easy") }
|
7
|
+
before do
|
8
|
+
Curl::Easy.stub(:http_post => fake_curb)
|
9
|
+
Curl::Easy.stub(:http_get => fake_curb)
|
10
|
+
end
|
11
|
+
|
12
|
+
subject { GnipRule::Client.new('https://api.gnip.com:443/accounts/foo/publishers/twitter/streams/track/prod/rules.json', 'username', 'password') }
|
13
|
+
|
14
|
+
describe '#initialize' do
|
15
|
+
it 'should convert XML URLs to JSON' do
|
16
|
+
subject.url.should == 'https://api.gnip.com:443/accounts/foo/publishers/twitter/streams/track/prod/rules.json'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe '#add' do
|
21
|
+
it 'should POST rule to the given URL with given credentials' do
|
22
|
+
Curl::Easy.should_receive(:http_post)
|
23
|
+
subject.add('value', 'tag')
|
24
|
+
end
|
25
|
+
|
26
|
+
xit 'should raise an error if we got a 4xx or 5xx HTTP status'
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#delete' do
|
30
|
+
it 'should POST rule json to a URL with given credentials' do
|
31
|
+
Curl::Easy.should_receive(:http_post)
|
32
|
+
subject.delete('value', 'tag')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#list' do
|
37
|
+
it 'should GET a URL with given credentials' do
|
38
|
+
Curl::Easy.should_receive(:http_get)
|
39
|
+
subject.list()
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#jsonify_rules' do
|
44
|
+
it 'should JSONify Strings' do
|
45
|
+
json = subject.jsonify_rules('foo', 'bar')
|
46
|
+
json.should == '{"rules":[{"value":"foo","tag":"bar"}]}'
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should JSONify Rules' do
|
50
|
+
json = subject.jsonify_rules(GnipRule::Rule.new('baz', 'foo'))
|
51
|
+
json.should == '{"rules":[{"value":"baz","tag":"foo"}]}'
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'should JSONify an Array of Strings with a tag' do
|
55
|
+
json = subject.jsonify_rules(['foo', 'bar'], 'baz')
|
56
|
+
json.should == '{"rules":[{"value":"foo","tag":"baz"},{"value":"bar","tag":"baz"}]}'
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should JSONify an Array of Rules' do
|
60
|
+
rule1 = GnipRule::Rule.new('baz', 'foo')
|
61
|
+
rule2 = GnipRule::Rule.new('bar', 'thing')
|
62
|
+
json = subject.jsonify_rules([rule1, rule2])
|
63
|
+
json.should == '{"rules":[{"value":"baz","tag":"foo"},{"value":"bar","tag":"thing"}]}'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec-helper'
|
2
|
+
|
3
|
+
require 'gnip-rule/rule'
|
4
|
+
|
5
|
+
describe GnipRule::Rule do
|
6
|
+
describe '#initialize' do
|
7
|
+
it 'should allow an optional tag' do
|
8
|
+
rule = GnipRule::Rule.new('value')
|
9
|
+
rule.tag.should == nil
|
10
|
+
|
11
|
+
rule_with_tag = GnipRule::Rule.new('value', 'tag')
|
12
|
+
rule_with_tag.tag.should == 'tag'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#valid?' do
|
17
|
+
it 'should consider rules with "stop words" to be invalid' do
|
18
|
+
rule = GnipRule::Rule.new('an value')
|
19
|
+
rule.valid?.should == false
|
20
|
+
end
|
21
|
+
it 'should consider rules that are too long to be invalid' do
|
22
|
+
rule = GnipRule::Rule.new('01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789')
|
23
|
+
rule.valid?.should == false
|
24
|
+
end
|
25
|
+
it 'should consider empty sources to be invalid' do
|
26
|
+
rule = GnipRule::Rule.new('foo source: bar')
|
27
|
+
rule.valid?.should == false
|
28
|
+
end
|
29
|
+
it 'should consider negative ORs to be invalid' do
|
30
|
+
rule = GnipRule::Rule.new('-iphone OR ipad')
|
31
|
+
rule.valid?.should == false
|
32
|
+
end
|
33
|
+
it 'should consider rules with more than 10 positive terms invalid' do
|
34
|
+
rule = GnipRule::Rule.new('one two three four five six seven eight nine ten eleven')
|
35
|
+
rule.valid?.should == false
|
36
|
+
end
|
37
|
+
it 'should consider stop words within quotes to be valid' do
|
38
|
+
rule = GnipRule::Rule.new('"foo the bar" baz')
|
39
|
+
rule.valid?.should == true
|
40
|
+
end
|
41
|
+
it 'should consider rules without "stop words" to be valid' do
|
42
|
+
rule = GnipRule::Rule.new('value')
|
43
|
+
rule.valid?.should == true
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#as_json' do
|
48
|
+
it 'should omit tag if tag not defined' do
|
49
|
+
rule = GnipRule::Rule.new('foo')
|
50
|
+
rule.as_json.should == '{"value":"foo"}'
|
51
|
+
end
|
52
|
+
it 'should add tag if defined' do
|
53
|
+
rule = GnipRule::Rule.new('foo', 'bar')
|
54
|
+
rule.as_json.should == '{"value":"foo","tag":"bar"}'
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/spec/spec-helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gnip-rule
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Eric Wendelin
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-19 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: curb
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.8.0
|
38
|
+
- - <
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.9.0
|
41
|
+
type: :runtime
|
42
|
+
prerelease: false
|
43
|
+
version_requirements: !ruby/object:Gem::Requirement
|
44
|
+
none: false
|
45
|
+
requirements:
|
46
|
+
- - ! '>='
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: 0.8.0
|
49
|
+
- - <
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: 0.9.0
|
52
|
+
- !ruby/object:Gem::Dependency
|
53
|
+
name: json
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ! '>='
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: 1.6.0
|
60
|
+
- - <
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.7.0
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
none: false
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: 1.6.0
|
71
|
+
- - <
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: 1.7.0
|
74
|
+
description: Ruby library for working with the Gnip Rules API
|
75
|
+
email:
|
76
|
+
- me@eriwen.com
|
77
|
+
executables: []
|
78
|
+
extensions: []
|
79
|
+
extra_rdoc_files: []
|
80
|
+
files:
|
81
|
+
- .gitignore
|
82
|
+
- .pryrc
|
83
|
+
- .rvmrc
|
84
|
+
- .travis.yml
|
85
|
+
- Gemfile
|
86
|
+
- LICENSE
|
87
|
+
- README.md
|
88
|
+
- Rakefile
|
89
|
+
- gnip-rule.gemspec
|
90
|
+
- lib/gnip-rule.rb
|
91
|
+
- lib/gnip-rule/client.rb
|
92
|
+
- lib/gnip-rule/rule.rb
|
93
|
+
- lib/gnip-rule/version.rb
|
94
|
+
- spec/gnip-rule/client_spec.rb
|
95
|
+
- spec/gnip-rule/rule_spec.rb
|
96
|
+
- spec/spec-helper.rb
|
97
|
+
homepage: https://github.com/eriwen/gnip-rule
|
98
|
+
licenses: []
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
none: false
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
none: false
|
111
|
+
requirements:
|
112
|
+
- - ! '>='
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '0'
|
115
|
+
requirements: []
|
116
|
+
rubyforge_project: gnip-rule
|
117
|
+
rubygems_version: 1.8.24
|
118
|
+
signing_key:
|
119
|
+
specification_version: 3
|
120
|
+
summary: Ruby library for working with the Gnip Rules API
|
121
|
+
test_files:
|
122
|
+
- spec/gnip-rule/client_spec.rb
|
123
|
+
- spec/gnip-rule/rule_spec.rb
|
124
|
+
- spec/spec-helper.rb
|