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.
@@ -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