gnip-rule 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,6 @@
1
+ *.gem
2
+ .bundle
3
+ .idea
4
+ Gemfile.lock
5
+ pkg/*
6
+ .rbx
data/.pryrc ADDED
@@ -0,0 +1,2 @@
1
+ $: << "/Users/eric/src/gnip-rule/lib/"
2
+ require 'gnip-rule'
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use 1.9.3@gnip-rule --create
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 1.8.7
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'http://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gnip-rule.gemspec
4
+ gemspec
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.
@@ -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
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -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
@@ -0,0 +1,7 @@
1
+ require 'gnip-rule/version'
2
+
3
+ require 'gnip-rule/rule'
4
+ require 'gnip-rule/client'
5
+
6
+ module GnipRule
7
+ end
@@ -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,3 @@
1
+ module GnipRule
2
+ VERSION = '0.1.1'
3
+ 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
@@ -0,0 +1,4 @@
1
+ require 'bundler'
2
+ Bundler.setup
3
+
4
+ require 'rspec'
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