gnip-rule 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|