gnip_api 0.0.1 → 0.0.2

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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/Gemfile.lock +6 -1
  6. data/README.md +43 -4
  7. data/gnip_api.gemspec +1 -0
  8. data/lib/gnip_api/adapter.rb +44 -22
  9. data/lib/gnip_api/adapters/base_adapter.rb +59 -0
  10. data/lib/gnip_api/adapters/httparty_adapter.rb +33 -1
  11. data/lib/gnip_api/apis/power_track/buffer.rb +4 -0
  12. data/lib/gnip_api/apis/power_track/rule.rb +31 -0
  13. data/lib/gnip_api/apis/power_track/rules.rb +69 -2
  14. data/lib/gnip_api/apis/power_track/stream.rb +41 -22
  15. data/lib/gnip_api/apis/search/count.rb +0 -0
  16. data/lib/gnip_api/apis/search/query.rb +36 -0
  17. data/lib/gnip_api/apis/search/result.rb +17 -0
  18. data/lib/gnip_api/apis/search/stream.rb +26 -0
  19. data/lib/gnip_api/configuration.rb +4 -1
  20. data/lib/gnip_api/endpoints.rb +15 -2
  21. data/lib/gnip_api/errors.rb +39 -0
  22. data/lib/gnip_api/gnip/activity.rb +72 -0
  23. data/lib/gnip_api/gnip/actor.rb +42 -11
  24. data/lib/gnip_api/gnip/gnip_data.rb +23 -0
  25. data/lib/gnip_api/gnip/message.rb +24 -51
  26. data/lib/gnip_api/gnip/system_message.rb +30 -0
  27. data/lib/gnip_api/gnip/url.rb +35 -0
  28. data/lib/gnip_api/limiters/rules.rb +56 -0
  29. data/lib/gnip_api/rate_limiter.rb +14 -0
  30. data/lib/gnip_api/request.rb +26 -0
  31. data/lib/gnip_api/response.rb +35 -0
  32. data/lib/gnip_api/version.rb +1 -1
  33. data/lib/gnip_api.rb +31 -0
  34. data/spec/fixtures/activities/full_activity.json +227 -0
  35. data/spec/fixtures/activities/nil_urls.json +1 -0
  36. data/spec/fixtures/activities/real_activity.json +127 -0
  37. data/spec/fixtures/activities/real_activity_long_rules.json +126 -0
  38. data/spec/fixtures/system_messages/error.json +1 -0
  39. data/spec/fixtures/system_messages/info.json +1 -0
  40. data/spec/fixtures/system_messages/warn.json +1 -0
  41. data/spec/fixtures/twitter_messages/quote.json +219 -0
  42. data/spec/fixtures/twitter_messages/retweet.json +418 -0
  43. data/spec/fixtures/twitter_messages/retweet_long_rules.json +417 -0
  44. data/spec/fixtures/twitter_messages/scrub_geo.json +11 -0
  45. data/spec/fixtures/twitter_messages/status_delete.json +11 -0
  46. data/spec/fixtures/twitter_messages/status_withheld.json +11 -0
  47. data/spec/fixtures/twitter_messages/tweet.json +233 -0
  48. data/spec/fixtures/twitter_messages/tweet_long_rules.json +232 -0
  49. data/spec/fixtures/twitter_messages/user_delete.json +7 -0
  50. data/spec/fixtures/twitter_messages/user_protect.json +7 -0
  51. data/spec/fixtures/twitter_messages/user_suspend.json +7 -0
  52. data/spec/fixtures/twitter_messages/user_undelete.json +7 -0
  53. data/spec/fixtures/twitter_messages/user_unprotect.json +7 -0
  54. data/spec/fixtures/twitter_messages/user_unsuspend.json +7 -0
  55. data/spec/fixtures/twitter_messages/user_withheld.json +10 -0
  56. data/spec/gnip_api/adapter_spec.rb +78 -0
  57. data/spec/gnip_api/adapters/base_adapter_spec.rb +0 -0
  58. data/spec/gnip_api/adapters/httparty_adapter_spec.rb +0 -0
  59. data/spec/gnip_api/apis/power_track/rule_spec.rb +62 -0
  60. data/spec/gnip_api/apis/power_track/rules_spec.rb +70 -0
  61. data/spec/gnip_api/apis/power_track/stream_spec.rb +50 -0
  62. data/spec/gnip_api/gnip/activity_spec.rb +123 -0
  63. data/spec/gnip_api/gnip/gnip_data_spec.rb +108 -0
  64. data/spec/gnip_api/gnip/message_spec.rb +48 -0
  65. data/spec/gnip_api/limiters/rules_spec.rb +74 -0
  66. data/spec/gnip_api/request_spec.rb +33 -0
  67. data/spec/gnip_api/response_spec.rb +32 -0
  68. data/spec/lib/test_adapter.rb +16 -0
  69. data/spec/spec_helper.rb +8 -0
  70. metadata +103 -2
@@ -0,0 +1,39 @@
1
+ module GnipApi
2
+ module Errors
3
+ module Adapter
4
+ class RequestError < StandardError
5
+ def initialize msg='Request failed'
6
+ @message = msg
7
+ end
8
+ end
9
+ end
10
+
11
+ module PowerTrack
12
+ class MissingRules < StandardError
13
+ def initialize
14
+ @message = 'No rules provided to operate'
15
+ end
16
+ end
17
+ end
18
+
19
+ class MissingCredentials < StandardError
20
+ def initialize
21
+ @message = 'No credentials provided'
22
+ end
23
+ end
24
+
25
+ class MissingAdapter < StandardError
26
+ def initialize
27
+ @message = 'No adapter selected'
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ module Gnip
34
+ class UndefinedMessage < StandardError
35
+ def initialize
36
+ @message = 'Could not recognize message received'
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,72 @@
1
+ module Gnip
2
+ class Activity < Gnip::Message
3
+ attr_reader :id, :object_type, :actor, :verb, :posted_time, :generator, :provider, :link,
4
+ :body, :object, :favorites_count, :twitter_entities, :twitter_filter_level, :twitter_lang,
5
+ :retweet_count, :gnip
6
+
7
+ def initialize params = {}
8
+ @id = params['id']
9
+ @object_type = params['objectType']
10
+ @actor = Gnip::Actor.new params['actor']
11
+ @verb = params['verb']
12
+ @posted_time = params['postedTime']
13
+ @generator = params['generator']
14
+ @provider = params['provider']
15
+ @link = params['link']
16
+ @body = params['body']
17
+ @object = retweet? ? Gnip::Activity.new(params['object']) : params['object']
18
+ @favorites_count = params['favoritesCount']
19
+ @twitter_entities = params['twitter_entities']
20
+ @twitter_filter_level = params['twitter_filter_level']
21
+ @twitter_lang = params['twitter_lang']
22
+ @retweet_count = params['retweetCount']
23
+ @gnip = Gnip::GnipData.new(params['gnip']) if params['gnip']
24
+ end
25
+
26
+ def original_attributes
27
+ {
28
+ :id => @id,
29
+ :objectType => @object_type,
30
+ :actor => @actor.original_attributes,
31
+ :verb => @verb,
32
+ :postedTime => @posted_time,
33
+ :generator => @generator,
34
+ :provider => @provider,
35
+ :link => @link,
36
+ :body => @body,
37
+ :object => @object.kind_of?(Gnip::Activity) ? @object.original_attributes : @object,
38
+ :favoritesCount => @favorites_count,
39
+ :twitter_entities => @twitter_entities,
40
+ :twitter_filter_level => @twitter_filter_level,
41
+ :twitter_lang => @twitter_lang,
42
+ :retweetCount => @retweet_count,
43
+ :gnip => @gnip ? @gnip.original_attributes : nil
44
+ }
45
+ end
46
+
47
+ def posted_time
48
+ DateTime.parse(@posted_time)
49
+ end
50
+
51
+ def link
52
+ URI(@link)
53
+ end
54
+
55
+ def tweet_id
56
+ @id.split(':').last
57
+ end
58
+
59
+ def to_json
60
+ generate_json(original_attributes)
61
+ end
62
+
63
+ def author
64
+ actor.display_name
65
+ end
66
+
67
+ def retweet?
68
+ verb == 'share'
69
+ end
70
+ end
71
+ end
72
+
@@ -1,34 +1,65 @@
1
1
  module Gnip
2
- class Actor
3
- attr_accessor :id, :object_type, :link, :display_name, :image, :summary,
4
- :location, :friends_count, :followers_count, :statuses_count
2
+ class Actor < Gnip::Message
3
+ attr_reader :object_type, :id, :link, :display_name, :posted_time, :image, :summary,
4
+ :links, :friends_count, :followers_count, :statuses_count, :twitter_time_zone, :verified,
5
+ :utc_offset, :preferred_username, :languages, :location, :favorites_count
5
6
 
6
7
  def initialize params = {}
7
- @id = params['id']
8
8
  @object_type = params['objectType']
9
+ @id = params['id']
9
10
  @link = params['link']
10
11
  @display_name = params['displayName']
12
+ @posted_time = params['postedTime']
11
13
  @image = params['image']
12
14
  @summary = params['summary']
13
- @location = params['location']
15
+ @links = params['links']
14
16
  @friends_count = params['friendsCount']
15
17
  @followers_count = params['followersCount']
18
+ @listed_count = params['listedCount']
16
19
  @statuses_count = params['statusesCount']
20
+ @twitter_time_zone = params['twitterTimeZone']
21
+ @verified = params['verified']
22
+ @utc_offset = params['utcOffset']
23
+ @preferred_username = params['preferredUsername']
24
+ @languages = params['languages'].join(',')
25
+ @location = params['location']
26
+ @favorites_count = params['favoritesCount']
17
27
  end
18
28
 
19
- def to_json
29
+ def original_attributes
20
30
  {
31
+ :objectType => @object_type,
21
32
  :id => @id,
22
- :object_type => @object_type,
23
33
  :link => @link,
24
- :display_name => @display_name,
34
+ :displayName => @display_name,
35
+ :postedTime => @posted_time,
25
36
  :image => @image,
26
37
  :summary => @summary,
38
+ :links => @links,
39
+ :friendsCount => @friends_count,
40
+ :followersCount => @followers_count,
41
+ :listedCount => @listed_count,
42
+ :statusesCount => @statuses_count,
43
+ :twitterTimeZone => @twitter_time_zone,
44
+ :verified => @verified,
45
+ :utcOffset => @utc_offset,
46
+ :preferredUsername => @preferred_username,
47
+ :languages => @languages.split(','),
27
48
  :location => @location,
28
- :friends_count => @friends_count,
29
- :followers_count => @followers_count,
30
- :statuses_count => @statuses_count
49
+ :favoritesCount => @favorites_count
31
50
  }
32
51
  end
52
+
53
+ def user_id
54
+ @id.split(':').last
55
+ end
56
+
57
+ def image
58
+ URI(@image)
59
+ end
60
+
61
+ def to_json
62
+ generate_json(original_attributes)
63
+ end
33
64
  end
34
65
  end
@@ -0,0 +1,23 @@
1
+ module Gnip
2
+ class GnipData < Gnip::Message
3
+ attr_reader :matching_rules, :urls, :language
4
+
5
+ def initialize params={}
6
+ @matching_rules = params['matching_rules'].map{|r| GnipApi::Apis::PowerTrack::Rule.new(r)} if params['matching_rules']
7
+ @urls = (params['urls'] ? params['urls'].map{|u| Gnip::Url.new(u)} : [])
8
+ @language = params['language']
9
+ end
10
+
11
+ def original_attributes
12
+ {
13
+ :matching_rules => @matching_rules.map(&:attributes),
14
+ :urls => @urls.map(&:original_attributes),
15
+ :language => @language
16
+ }.delete_if{|k,v| v.nil?}
17
+ end
18
+
19
+ def to_json
20
+ generate_json(original_attributes)
21
+ end
22
+ end
23
+ end
@@ -1,71 +1,44 @@
1
1
  module Gnip
2
2
  class Message
3
+ SYSTEM_MESSAGE_TYPES = ['error', 'warn', 'info']
4
+
3
5
  def self.build params
4
- if params['error'] || params['warn'] || params['info']
5
- SystemMessage.new params
6
- elsif params['id']
7
- Activity.new params
8
- end
6
+ return build_system_message(params) if (SYSTEM_MESSAGE_TYPES & params.keys).any?
7
+ return build_activity(params) if params['objectType'] && params['objectType'] == 'activity'
8
+ raise Gnip::UndefinedMessage
9
9
  end
10
10
 
11
11
  def system_message?
12
- false
12
+ @message_type ? true : false
13
13
  end
14
14
 
15
- def activity?
16
- false
15
+ def error?
16
+ @message_type == 'error'
17
17
  end
18
- end
19
-
20
- class SystemMessage < Message
21
- attr_accessor :message, :sent
22
-
23
- def initialize params
24
- @message = params['message']
25
- @sent = params['sent']
18
+
19
+ def warn?
20
+ @message_type == 'warn'
26
21
  end
27
-
28
- def system_message?
29
- true
30
- end
31
- end
32
-
33
- class Activity < Message
34
- attr_accessor :id, :actor, :object_type, :verb, :posted_time, :provider, :link, :body
35
- def initialize params = {}
36
- @id = params['id']
37
- @object_type = params['objectType']
38
- @verb = params['verb']
39
- @posted_time = params['postedTime']
40
- @provider = params['provider']
41
- @link = params['link']
42
- @body = retweet? ? params['object']['body'] : params['body']
43
- @actor = Actor.new params['actor']
22
+
23
+ def info?
24
+ @message_type == 'info'
44
25
  end
45
26
 
46
- def to_json
47
- {
48
- :id => @id,
49
- :actor => @actor.to_json,
50
- :object_type => @object_type,
51
- :verb => @verb,
52
- :posted_time => @posted_time,
53
- :provider => @provider,
54
- :link => @link,
55
- :body => @body
56
- }.to_json
27
+ def activity?
28
+ @object_type == 'activity'
57
29
  end
58
-
59
- def author
60
- actor.display_name
30
+
31
+ def generate_json data
32
+ JSON.generate(data)
61
33
  end
62
34
 
63
- def activity?
64
- true
35
+ private
36
+ def self.build_system_message params
37
+ Gnip::SystemMessage.new params
65
38
  end
66
39
 
67
- def retweet?
68
- verb == 'share'
40
+ def self.build_activity params
41
+ Gnip::Activity.new params
69
42
  end
70
43
  end
71
44
  end
@@ -0,0 +1,30 @@
1
+ module Gnip
2
+ class SystemMessage < Gnip::Message
3
+ attr_reader :message, :sent, :message_type
4
+
5
+ def initialize params
6
+ @message_type = params.keys.first
7
+ @message = params['message']
8
+ @sent = params['sent']
9
+ end
10
+
11
+ def original_attributes
12
+ {
13
+ @message_type => @message,
14
+ :sent => @sent
15
+ }
16
+ end
17
+
18
+ def log_method
19
+ @message_type.to_sym
20
+ end
21
+
22
+ def message
23
+ @message.strip
24
+ end
25
+
26
+ def to_json
27
+ parse_json(original_attributes)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,35 @@
1
+ module Gnip
2
+ class Url < Gnip::Message
3
+ attr_reader :url, :expanded_url, :expanded_status, :display_url, :indices
4
+
5
+ def initialize params={}
6
+ @url = params['url']
7
+ @expanded_url = params['expanded_url']
8
+ @display_url = params['display_url']
9
+ @expanded_status = params['expanded_status']
10
+ @indices = params['indices']
11
+ end
12
+
13
+ def url
14
+ URI(@url) unless @url.nil?
15
+ end
16
+
17
+ def expanded_url
18
+ URI(@expanded_url) unless @url.nil?
19
+ end
20
+
21
+ def original_attributes
22
+ {
23
+ :url => @url,
24
+ :display_url => @display_url,
25
+ :expanded_url => @expanded_url,
26
+ :expanded_status => @expanded_status,
27
+ :indices => @indices
28
+ }.delete_if{|k,v| v.nil?}
29
+ end
30
+
31
+ def to_json
32
+ generate_json(original_attributes)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,56 @@
1
+ module GnipApi
2
+ module Limiters
3
+ module Rules
4
+
5
+ def rules_init
6
+ @rules_last_reset = Time.now
7
+ @rules_requests = 0
8
+ end
9
+
10
+ def rules_request_allowed?
11
+ mutex.synchronize do
12
+ reset_rules_if_expired!
13
+ add_rules_request!
14
+ return true if @rules_requests <= rules_max_requests
15
+ return false
16
+ end
17
+ end
18
+
19
+ def reset_rules_if_expired!
20
+ if seconds_since_last_rules_request >= rules_expire
21
+ reset_rules!
22
+ end
23
+ end
24
+
25
+ def seconds_since_last_rules_request
26
+ Time.now.to_i - @rules_last_reset.to_i
27
+ end
28
+
29
+ def add_rules_request!
30
+ @rules_requests += 1
31
+ end
32
+
33
+ def reset_rules!
34
+ @rules_last_reset = Time.now
35
+ @rules_requests = 0
36
+ end
37
+
38
+ def rules_last_reset
39
+ @rules_last_reset
40
+ end
41
+
42
+ def rules_requests
43
+ @rules_requests
44
+ end
45
+
46
+ def rules_max_requests
47
+ 5
48
+ end
49
+
50
+ def rules_expire
51
+ 1
52
+ end
53
+
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,14 @@
1
+ module GnipApi
2
+ class RateLimiter
3
+ include GnipApi::Limiters::Rules
4
+
5
+ def initialize
6
+ self.rules_init
7
+ end
8
+
9
+ private
10
+ def mutex
11
+ GnipApi.config.mutex
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,26 @@
1
+ module GnipApi
2
+ class Request
3
+ attr_reader :uri, :payload, :headers, :request_method
4
+
5
+ class << self
6
+ def new_get uri, headers=nil
7
+ new(:uri => uri, :headers => headers, :request_method => GnipApi::Adapter::GET, )
8
+ end
9
+
10
+ def new_post uri, payload, headers=nil
11
+ new(:uri => uri, :headers => headers, :payload => payload, :request_method => GnipApi::Adapter::POST)
12
+ end
13
+
14
+ def new_delete uri, payload, headers=nil
15
+ new(:uri => uri, :headers => headers, :payload => payload, :request_method => GnipApi::Adapter::DELETE)
16
+ end
17
+ end
18
+
19
+ def initialize params={}
20
+ @uri = params[:uri]
21
+ @payload = params[:payload]
22
+ @headers = params[:headers]
23
+ @request_method = params[:request_method]
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,35 @@
1
+ module GnipApi
2
+ class Response
3
+ # List of codes that are considered OK
4
+ OK_STATUSES = [200, 201, 202, 203, 204, 205, 206, 207, 208, 226]
5
+
6
+ attr_reader :body, :headers, :status, :request
7
+
8
+ def initialize request, status, body, headers
9
+ @status = status
10
+ @body = body
11
+ @headers = headers
12
+ @request = request
13
+ end
14
+
15
+ def request_method
16
+ @request.request_method
17
+ end
18
+
19
+ def request_uri
20
+ @request.uri
21
+ end
22
+
23
+ def ok?
24
+ OK_STATUSES.include? @status
25
+ end
26
+
27
+ def error_message
28
+ if @body && !@body.empty?
29
+ parsed = JSON.parse(@body)
30
+ return parsed['error']['message'] if parsed['error']
31
+ end
32
+ return nil
33
+ end
34
+ end
35
+ end
@@ -1,3 +1,3 @@
1
1
  module GnipApi
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/gnip_api.rb CHANGED
@@ -1,13 +1,28 @@
1
1
  require "gnip_api/version"
2
+ require "gnip_api/errors"
2
3
  require "gnip_api/configuration"
3
4
  require "gnip_api/endpoints"
5
+ require "gnip_api/limiters/rules"
6
+ require "gnip_api/rate_limiter"
4
7
  require "gnip_api/apis/power_track/stream"
5
8
  require "gnip_api/apis/power_track/rules"
6
9
  require "gnip_api/apis/power_track/buffer"
10
+ require "gnip_api/apis/power_track/rule"
11
+ require "gnip_api/apis/search/stream"
12
+ require "gnip_api/apis/search/count"
13
+ require "gnip_api/apis/search/query"
14
+ require "gnip_api/apis/search/result"
7
15
  require "gnip_api/gnip/message"
16
+ require "gnip_api/gnip/system_message"
8
17
  require "gnip_api/gnip/actor"
18
+ require "gnip_api/gnip/activity"
19
+ require "gnip_api/gnip/gnip_data"
20
+ require "gnip_api/gnip/url"
9
21
  require "gnip_api/adapter"
22
+ require "gnip_api/adapters/base_adapter"
10
23
  require "gnip_api/adapters/httparty_adapter"
24
+ require "gnip_api/response"
25
+ require "gnip_api/request"
11
26
 
12
27
  # External
13
28
  require 'httparty'
@@ -32,5 +47,21 @@ module GnipApi
32
47
  def logger
33
48
  self.configuration.logger
34
49
  end
50
+
51
+ def rate_limiter
52
+ self.configuration.rate_limiter
53
+ end
54
+
55
+ def config
56
+ self.configuration
57
+ end
58
+
59
+ def credentials?
60
+ @configuration.user && @configuration.password && @configuration.account
61
+ end
62
+
63
+ def adapter_class?
64
+ @configuration.adapter_class ? true : false
65
+ end
35
66
  end
36
67
  end