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
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dbd9204b40905addd74370eaac461f346a222cdf
4
- data.tar.gz: 86b9866f63329adf2e63f82431cb8dec3bf489cf
3
+ metadata.gz: 74edd623bf1f6bb85470235633add59192a90448
4
+ data.tar.gz: 51786aa16a0f9df12bf3e44595441096e0e0db1c
5
5
  SHA512:
6
- metadata.gz: 3b0a11c8baa694d2e5da35342f7aaa1140386d3fd1f6da1fc9c9d90f4a67546d9d03400b72548315705a8f26e8a4d1889ae60ca7b7fee88ac82741ff5b9c4f56
7
- data.tar.gz: de879b08e0fe1c5c7b0f6eed2dff14190c6418fa757b36933c89adee5d8b928791c123458489e6fb21e4aae32a0c594985dbaa2e6dd67ae35e18a3e82b3ddb24
6
+ metadata.gz: e49dafce62bb9f34c05127676b6099ee687c35667d849d609e241cf198c11196069b41f7ab979ee3a67a5f56d670bf4fd07cf7a1a5f1642aa367ff56724427f2
7
+ data.tar.gz: c88927e42d3da21e5b8ebd59ae391733d8f79a50e5d42c77c21498368a161827790329da94a80a100b66856a4f91b5c302407235d0c9ba72edce2434ee489aff
data/.gitignore CHANGED
@@ -19,4 +19,5 @@ coverage/*
19
19
  *.iml
20
20
  .rvmrc
21
21
  dump.rdb
22
- test_env.rb
22
+ test_env.rb
23
+ pkg
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ gnip_api
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.1.0
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gnip_api (0.0.1)
4
+ gnip_api (0.0.2)
5
5
  activesupport
6
6
  httparty
7
7
  json
@@ -45,6 +45,7 @@ GEM
45
45
  rspec-support (3.0.3)
46
46
  slop (3.6.0)
47
47
  thread_safe (0.3.5)
48
+ timecop (0.7.1)
48
49
  tzinfo (1.2.2)
49
50
  thread_safe (~> 0.1)
50
51
 
@@ -58,3 +59,7 @@ DEPENDENCIES
58
59
  pry
59
60
  rake (~> 10.0)
60
61
  rspec
62
+ timecop
63
+
64
+ BUNDLED WITH
65
+ 1.10.4
data/README.md CHANGED
@@ -1,8 +1,13 @@
1
1
  # GnipApi
2
2
 
3
- You can connect with Gnip APIs with this gem and operate data. For now there's only a basic set of apis implemented, but I plan to include more in the future.
4
- The PowerTrack stream consumer is available as well as the listing of rules. Full rules operation will be included later.
5
- Also the gem will support different adapters, currently it's dependent of HTTParty, but I plan to remove this dependency and let the user choose which adapter to use, which can be a custom one of course. You will be able to define your own adapter to handle the http connections.
3
+ Connect with different Gnip APIs and get data from streams.
4
+
5
+ ## Notes
6
+
7
+ - Can't access Search API currently
8
+ - Rules endpoint are now rate limited.
9
+ - A simple rate limiter was implemented.
10
+ - You can configure the gem's mutex outside the gem if you plan to have concurrency. Very experimental for now.
6
11
 
7
12
  ## Installation
8
13
 
@@ -22,7 +27,39 @@ Or install it yourself as:
22
27
 
23
28
  ## Usage
24
29
 
25
- TODO
30
+ ### Configure the gem
31
+
32
+ ```ruby
33
+ GnipApi.configure |config|
34
+ config.user = 'someone' # Gnip Account Username
35
+ config.password = 'something' # Gnip Password
36
+ config.account = 'myGnipAccount' # Your accounts name
37
+ config.adapter_class = SomeAdapter # You can define your own adapter, more in the following section
38
+ config.logger = Logger.new('myLog.log') # You can also provide a custom logger
39
+ config.mutex = Mutex.new # Experimental thread safety, more below
40
+ end
41
+ ```
42
+
43
+ Put the avobe code in a initializer if you're using Rails, or somewhere else if you aren't. After that you can interact with Gnip APIs.
44
+
45
+ Note that you'll need a source and a label. Source is the data source within Gnip, such as Twitter, and label is the identifier of your stream.
46
+
47
+ ### Adapters
48
+
49
+ GnipApi is not dependent of a single adapter (there's a dependency with HTTParty, but shhh... it won't last too long). You can use one of the provided adapters, or you can make your own, using the BaseAdapter class. You only need to implement the desired connector POST, GET and DELETE methods. There's an extra stream_get method, but it's just a variant of GET.
50
+
51
+ The custom adapter does not require to live within the gem files, as long as GnipApi has access to your class, just put it in the config and you're ready to go. See the current adapters for reference.
52
+
53
+ ### Mutex and Thread Safety
54
+
55
+ GnipApi has this feature in experimental stage, using a simple mutex to interact with the RateLimiter. The limiters are very simple, and should prevent your code executing more requests than it should. Depending where you are defining the mutex, you can elevate the coverage. GnipApi only requires an instance of Mutex, which you can place somewhere else for it to use.
56
+
57
+ ## WIP State
58
+
59
+ GnipApi is still a WIP. Call it a beta, alpha, gem that has part of the features, whatever. Thing is, that it is currently usable. The custom adapter feature is there, and some of the APIs of Gnip were implemented. I'll be coding more things into this, such as other APIs, more limiters, request retries, error handling, different adapters for known connectors like RestClient or HTTP/net, etc.
60
+
61
+ In any case, you were warned about it. Feel free to fill my issues list on Github :)
62
+
26
63
 
27
64
  ## Contributing
28
65
 
@@ -31,3 +68,5 @@ TODO
31
68
  3. Commit your changes (`git commit -am 'Add some feature'`)
32
69
  4. Push to the branch (`git push origin my-new-feature`)
33
70
  5. Create a new Pull Request
71
+
72
+ This library was constructed with the help of [Armando Andini](https://github.com/antico5) who provided the basis to connect with the Gnip APIs.
data/gnip_api.gemspec CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency "pry"
24
24
  spec.add_development_dependency "awesome_print"
25
25
  spec.add_development_dependency "rspec"
26
+ spec.add_development_dependency "timecop"
26
27
 
27
28
  spec.add_dependency "httparty"
28
29
  spec.add_dependency "json"
@@ -1,40 +1,62 @@
1
1
  module GnipApi
2
2
  class Adapter
3
+ GET = 'GET'
4
+ POST = 'POST'
5
+ DELETE = 'DELETE'
6
+
3
7
  attr_reader :adapter
4
8
 
5
9
  def initialize
6
- @adapter = DevAdapter.new # GnipApi.configuration.adapter_class.new
10
+ raise GnipApi::Errors::MissingCredentials unless GnipApi.credentials?
11
+ raise GnipApi::Errors::MissingAdapter unless GnipApi.adapter_class?
12
+ @adapter = GnipApi.config.adapter_class.new
13
+ @logger = GnipApi.config.logger
7
14
  end
8
15
 
9
- def get url
10
- DevAdapter.get url
16
+ def get request
17
+ log_request(request)
18
+ response = adapter.get(request)
19
+ check_response_for_errors(response)
20
+ return response.body unless response.body.empty?
21
+ return true
11
22
  end
12
23
 
13
- def stream_get url
14
- DevAdapter.stream_get url do |data|
15
- yield(data)
16
- end
24
+ def post request
25
+ log_request(request)
26
+ response = adapter.post(request)
27
+ check_response_for_errors(response)
28
+ return response.body unless response.body.empty?
29
+ return true
17
30
  end
18
- end
19
31
 
20
- class DevAdapter
21
- class << self
22
- def stream_get url
23
- HTTParty.get url, :basic_auth => auth do |data|
24
- yield(data)
25
- end
26
- end
32
+ def delete request
33
+ log_request(request)
34
+ response = adapter.delete(request)
35
+ check_response_for_errors(response)
36
+ return response.body unless response.body.empty?
37
+ return true
38
+ end
27
39
 
28
- def get url
29
- HTTParty.get url, :basic_auth => auth
40
+ def stream_get request
41
+ log_request(request)
42
+ adapter.stream_get(request) do |data|
43
+ yield(data)
30
44
  end
45
+ end
31
46
 
32
- def auth
33
- {
34
- :username => GnipApi.configuration.user,
35
- :password => GnipApi.configuration.password
36
- }
47
+ def check_response_for_errors response
48
+ if response.ok?
49
+ @logger.info "#{response.request_method} request to #{response.request_uri} returned with status #{response.status} OK"
50
+ else
51
+ error_message = response.error_message
52
+ @logger.error "#{response.request_method} request to #{response.request_uri} returned with status #{response.status} FAIL: #{error_message}"
53
+ raise GnipApi::Errors::Adapter::RequestError.new, error_message
37
54
  end
38
55
  end
56
+
57
+ private
58
+ def log_request request
59
+ @logger.info "Starting #{request.request_method} request to #{request.uri}"
60
+ end
39
61
  end
40
62
  end
@@ -0,0 +1,59 @@
1
+ # BaseAdapter should be used on any adapter for this gem. In order
2
+ # to create your own adapter you must inherit this class to
3
+ # let your adapter use the provided functionality of the gem. In
4
+ # other words, this just defines basic methods to provide the
5
+ # custom adapter with basic data.
6
+ #
7
+ # To create a custom adapter, create your class, and implement the
8
+ # following methods that GnipApi::Adapter will need.
9
+ #
10
+ # - #get
11
+ # - #post
12
+ # - #delete
13
+ # - #stream_get
14
+ #
15
+ # All single-request methods (stream_get not included), should
16
+ # return a GnipApi::Response object with:
17
+ #
18
+ # - status: integer value for status code (200, 403, etc)
19
+ # - body: raw body, no matter if it's json or xml, the implementation of the api will know this
20
+ # - headers: a hash with the response headers
21
+ #
22
+ # The response object is an effort to standarize the data and let Gnip::Adapter
23
+ # operate without the concern of the data format. The helper method to create
24
+ # this response is available in this class, and will be available to your class
25
+ # when you write your adapter.
26
+ #
27
+ # The process of parsing the headers to a hash, setting authorization headers or
28
+ # parsing response data to break it down to status, body and headers are responsabilities
29
+ # of your custom adapter class.
30
+ #
31
+ # Gnip::Adapter will pass your adapter a Gnip::Request object that contains:
32
+ #
33
+ # - uri: URI object with url, schema, etc
34
+ # - payload: a parsed text to send in the request's body
35
+ # - headers: a hash that may contain additional headers
36
+ #
37
+ # Your adapter should process this object and translate it into a relevant request for
38
+ # your desired connector. Note that payload and headers may be nil if not needed.
39
+ #
40
+ # Last thing to denote, GnipApi::Adapter will expect an instance of your adapter to use.
41
+ # What you do inside your adapter or how you implement a specific adapter is up to you.
42
+
43
+ module GnipApi
44
+ module Adapters
45
+ class BaseAdapter
46
+ def username
47
+ GnipApi.configuration.user
48
+ end
49
+
50
+ def password
51
+ GnipApi.configuration.password
52
+ end
53
+
54
+ def create_response request, status, body, headers
55
+ GnipApi::Response.new request, status, body, headers
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,6 +1,38 @@
1
1
  module GnipApi
2
2
  module Adapters
3
- class HTTPartyAdapter
3
+ class HTTPartyAdapter < GnipApi::Adapters::BaseAdapter
4
+ def post request
5
+ data = HTTParty.post request.uri, :basic_auth => auth, :body => request.payload
6
+ return response(request, data)
7
+ end
8
+
9
+ def delete request
10
+ data = HTTParty.delete request.uri, :basic_auth => auth, :body => request.payload
11
+ return response(request, data)
12
+ end
13
+
14
+ def get request
15
+ data = HTTParty.get request.uri, :basic_auth => auth
16
+ return response(request, data)
17
+ end
18
+
19
+ def stream_get request
20
+ HTTParty.get request.uri, :headers => request.headers, :basic_auth => auth do |data|
21
+ yield(data)
22
+ end
23
+ end
24
+
25
+ def auth
26
+ {
27
+ :username => username,
28
+ :password => password
29
+ }
30
+ end
31
+
32
+ def response request, data
33
+ create_response request, data.code, data.body, data.headers
34
+ end
35
+
4
36
  end
5
37
  end
6
38
  end
@@ -9,6 +9,10 @@ module GnipApi
9
9
  @data = ""
10
10
  end
11
11
 
12
+ def size
13
+ @data.size
14
+ end
15
+
12
16
  def insert! chunk
13
17
  @data << chunk
14
18
  end
@@ -0,0 +1,31 @@
1
+ module GnipApi
2
+ module Apis
3
+ module PowerTrack
4
+ class Rule
5
+ attr_accessor :value, :tag
6
+
7
+ def initialize params={}
8
+ @value = params[:value] || params['value']
9
+ @tag = params[:tag] || params['tag']
10
+ end
11
+
12
+ def to_json
13
+ attributes.to_json
14
+ end
15
+
16
+ def attributes
17
+ attrs = {}
18
+ attrs[:value] = @value if @value
19
+ attrs[:tag] = @tag if @tag
20
+ attrs
21
+ end
22
+
23
+ def uid
24
+ rule = @value
25
+ rule += "tag:#{@tag}" if @tag
26
+ Digest::SHA2.hexdigest(rule)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,15 +1,82 @@
1
+ # Gnip PowerTrack Rules API
2
+ #
3
+ # Create, delete and list rules of a powetrack stream.
4
+
1
5
  module GnipApi
2
6
  module Apis
3
7
  module PowerTrack
4
8
  class Rules
5
9
  attr_reader :adapter
6
10
 
7
- def initialize
11
+ # In order to do any operation, you need to specify:
12
+ # - label: the label of your stream
13
+ # - source: which data source to use (I think only twitter is available)
14
+ def initialize params={}
8
15
  @adapter = GnipApi::Adapter.new
16
+ @label = params[:label]
17
+ @source = params[:source]
9
18
  end
10
19
 
20
+ # Returns an array of defined rules
11
21
  def list
12
- adapter.get GnipApi::Endpoints.powertrack_rules('twitter', 'prod')
22
+ request_allowed?
23
+ request = create_get_request
24
+ rules = adapter.get(request)
25
+ parse_rules(rules)
26
+ end
27
+
28
+ # Creates the specified rule. Parameters:
29
+ # - rules: GnipApi::Apis::PowerTrack::Rule object
30
+ def create rules
31
+ raise GnipApi::Errors::PowerTrack::MissingRules.new if rules.nil? || rules.empty?
32
+ request_allowed?
33
+ request = create_post_request(construct_rules(rules))
34
+ adapter.post(request)
35
+ end
36
+
37
+ # Deletes the specified rule. Parameters:
38
+ # - rules: GnipApi::Apis::PowerTrack::Rule object
39
+ def delete rules
40
+ raise GnipApi::Errors::PowerTrack::MissingRules.new if rules.nil? || rules.empty?
41
+ request_allowed?
42
+ request = create_delete_request(construct_rules(rules))
43
+ adapter.delete(request)
44
+ end
45
+
46
+ # Parses an array of GnipApi::Apis::PowerTrack::Rule objects
47
+ # to the necesary JSON format for the endpoint
48
+ def construct_rules rules
49
+ parsed_rules = {:rules => []}
50
+ rules.each do |rule|
51
+ parsed_rules[:rules] << rule.attributes
52
+ end
53
+ parsed_rules.to_json
54
+ end
55
+
56
+ def parse_rules data
57
+ parsed_data = JSON.parse(data)
58
+ parsed_data['rules'].map{|rule| GnipApi::Apis::PowerTrack::Rule.new(:value => rule['value'], :tag => rule['tag'])}
59
+ end
60
+
61
+ private
62
+ def endpoint
63
+ GnipApi::Endpoints.powertrack_rules(@source, @label)
64
+ end
65
+
66
+ def create_get_request
67
+ GnipApi::Request.new_get(endpoint)
68
+ end
69
+
70
+ def create_post_request payload
71
+ GnipApi::Request.new_post(endpoint, payload)
72
+ end
73
+
74
+ def create_delete_request payload
75
+ GnipApi::Request.new_delete(endpoint, payload)
76
+ end
77
+
78
+ def request_allowed?
79
+ raise 'RateLimited' unless GnipApi.config.rate_limiter.rules_request_allowed?
13
80
  end
14
81
  end
15
82
  end
@@ -2,7 +2,7 @@ module GnipApi
2
2
  module Apis
3
3
  module PowerTrack
4
4
  class Stream
5
- attr_reader :system_messages, :adapter
5
+ attr_reader :adapter
6
6
 
7
7
  def initialize params = {}
8
8
  @stream = params[:stream]
@@ -15,15 +15,53 @@ module GnipApi
15
15
  end
16
16
 
17
17
  def consume
18
- adapter.stream_get endpoint do |chunk|
18
+ request = create_request
19
+ adapter.stream_get request do |chunk|
19
20
  @buffer.insert! chunk
20
- yield(@buffer.read!)
21
+ begin
22
+ yield process_entries(@buffer.read!)
23
+ rescue Exception => e
24
+ puts e.class
25
+ puts e.message
26
+ puts e.backtrace[0..10].join("\n")
27
+ raise e
28
+ end
29
+ end
30
+ end
31
+
32
+ def process_entries entries
33
+ entries.map!{|e| parse_json(e)}.compact!
34
+ entries.map!{|e| build_message(e)}
35
+ log_system_messages(entries)
36
+ entries
37
+ end
38
+
39
+ def log_system_messages entries
40
+ entries.select{|message| message.system_message? }.each do |system_message|
41
+ GnipApi.logger.send(system_message.log_method, system_message.message)
42
+ end
43
+ end
44
+
45
+ def build_message params
46
+ Gnip::Message.build(params)
47
+ end
48
+
49
+ def parse_json json
50
+ begin
51
+ JSON.parse json
52
+ rescue JSON::ParserError
53
+ nil
21
54
  end
22
55
  end
23
56
 
24
57
  private
58
+ def create_request
59
+ GnipApi::Request.new_get(endpoint, {'Accept-Encoding' => 'gzip'})
60
+ end
25
61
 
26
62
  def set_config
63
+ raise 'MissingStream' if @stream.nil?
64
+ raise 'MissingSource' if @source.nil?
27
65
  @user = GnipApi.configuration.user
28
66
  @password = GnipApi.configuration.password
29
67
  @account = GnipApi.configuration.account
@@ -31,29 +69,10 @@ module GnipApi
31
69
  @buffer = GnipApi::Apis::PowerTrack::Buffer.new
32
70
  end
33
71
 
34
- def handle message
35
- @system_messages << message if message.system_message?
36
- yield message if message.activity?
37
- end
38
-
39
72
  def endpoint
40
73
  GnipApi::Endpoints.powertrack_stream(@source, @stream)
41
74
  end
42
75
 
43
- def parse data
44
- json_parse(extract_messages(data)).map { |hash| Message.build hash }
45
- end
46
-
47
- def json_parse messages
48
- messages.map do |message|
49
- begin
50
- JSON.parse message
51
- rescue JSON::ParserError
52
- nil
53
- end
54
- end.compact
55
- end
56
-
57
76
  end
58
77
  end
59
78
  end
File without changes
@@ -0,0 +1,36 @@
1
+ module GnipApi
2
+ module Apis
3
+ module Search
4
+ class Query
5
+ attr_accessor :rules, :from_date, :to_date, :max_results, :next, :publisher
6
+
7
+ def initialize params={}
8
+ @rules = params[:rules]
9
+ @from_date = params[:from_date]
10
+ @to_date = params[:to_date]
11
+ @max_results = params[:max_results]
12
+ @next = params[:next]
13
+ @publisher = params[:publisher]
14
+ end
15
+
16
+ def to_json
17
+ hash = {}
18
+ hash['query'] = @rules
19
+ hash['publisher'] = @publisher
20
+ hash['fromDate'] = @from_date.to_time.utc.strftime('%Y%m%d%H%M') if @from_date
21
+ hash['toDate'] = @to_date.to_time.utc.strftime('%Y%m%d%H%M') if @to_date
22
+ hash['next'] = @next if @next
23
+ hash['maxResults'] = @max_results if @max_results
24
+ hash.to_json
25
+ end
26
+
27
+ def valid?
28
+ end
29
+
30
+ private
31
+ def validate
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,17 @@
1
+ module GnipApi
2
+ module Apis
3
+ module Search
4
+ class Result
5
+ attr_reader :activities, :response
6
+
7
+ def initialize response
8
+ @response = response
9
+ end
10
+
11
+ def activities
12
+ @activities ||= response['results'].map { |activity| Activity.new(activity) }
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,26 @@
1
+ module GnipApi
2
+ module Apis
3
+ module Search
4
+ class Stream
5
+ attr_accessor :query, :label
6
+
7
+ def initialize options={}
8
+ @query = options[:query]
9
+ @label = options[:label]
10
+ @adapter = GnipApi::Adapter.new
11
+ end
12
+
13
+ def perform
14
+ response = @adapter.post search_url, @query.to_json
15
+ Result.new response
16
+ end
17
+
18
+ private
19
+
20
+ def search_url
21
+ GnipApi::Endpoints.search_stream(@label)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,10 +1,13 @@
1
1
  module GnipApi
2
2
  class Configuration
3
- attr_accessor :user, :password, :adapter_class, :account, :logger
3
+ attr_accessor :user, :password, :adapter_class, :account, :logger, :mutex
4
+ attr_reader :rate_limiter
4
5
 
5
6
  def initialize
6
7
  @adapter_class = GnipApi::Adapters::HTTPartyAdapter
7
8
  @logger = Logger.new('tmp/gnip_api.log')
9
+ @mutex = Mutex.new
10
+ @rate_limiter = GnipApi::RateLimiter.new
8
11
  end
9
12
  end
10
13
  end
@@ -2,11 +2,24 @@ module GnipApi
2
2
  class Endpoints
3
3
  class << self
4
4
  def powertrack_rules source, label
5
- URI("https://api.gnip.com:443/accounts/#{GnipApi.configuration.account}/publishers/#{source}/streams/track/#{label}/rules.json")
5
+ URI("https://api.gnip.com:443/accounts/#{account}/publishers/#{source}/streams/track/#{label}/rules.json")
6
6
  end
7
7
 
8
8
  def powertrack_stream source, label
9
- URI("https://stream.gnip.com:443/accounts/#{GnipApi.configuration.account}/publishers/#{source}/streams/track/#{label}.json")
9
+ URI("https://stream.gnip.com:443/accounts/#{account}/publishers/#{source}/streams/track/#{label}.json")
10
+ end
11
+
12
+ def search_stream label
13
+ URI("https://search.gnip.com/accounts/#{account}/search/#{label}.json")
14
+ end
15
+
16
+ def search_count
17
+ URI("https://search.gnip.com/accounts/#{ CONFIG['account'] }/search/#{label}.json/counts")
18
+ end
19
+
20
+ private
21
+ def account
22
+ GnipApi.configuration.account
10
23
  end
11
24
  end
12
25
  end