bwapi 1.0.0

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 (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.travis.yml +10 -0
  4. data/Gemfile +6 -0
  5. data/LICENCE.md +20 -0
  6. data/README.md +15 -0
  7. data/bin/bwapi +2 -0
  8. data/bwapi.gemspec +26 -0
  9. data/lib/bwapi.rb +28 -0
  10. data/lib/bwapi/authentication.rb +42 -0
  11. data/lib/bwapi/client.rb +54 -0
  12. data/lib/bwapi/client/admin.rb +35 -0
  13. data/lib/bwapi/client/admin/become.rb +21 -0
  14. data/lib/bwapi/client/admin/search.rb +41 -0
  15. data/lib/bwapi/client/admin/sub_clients.rb +109 -0
  16. data/lib/bwapi/client/admin/users.rb +95 -0
  17. data/lib/bwapi/client/admin/users/sharing.rb +35 -0
  18. data/lib/bwapi/client/brandwatch.rb +33 -0
  19. data/lib/bwapi/client/brandwatch/become.rb +19 -0
  20. data/lib/bwapi/client/brandwatch/client_modules.rb +26 -0
  21. data/lib/bwapi/client/client.rb +22 -0
  22. data/lib/bwapi/client/error_codes.rb +14 -0
  23. data/lib/bwapi/client/filters.rb +14 -0
  24. data/lib/bwapi/client/logout.rb +24 -0
  25. data/lib/bwapi/client/me.rb +42 -0
  26. data/lib/bwapi/client/oauth.rb +78 -0
  27. data/lib/bwapi/client/ping.rb +42 -0
  28. data/lib/bwapi/client/projects.rb +94 -0
  29. data/lib/bwapi/client/projects/categories.rb +70 -0
  30. data/lib/bwapi/client/projects/data.rb +62 -0
  31. data/lib/bwapi/client/projects/data_download.rb +49 -0
  32. data/lib/bwapi/client/projects/facebook_queries.rb +55 -0
  33. data/lib/bwapi/client/projects/queries.rb +99 -0
  34. data/lib/bwapi/client/projects/queries/backfill.rb +63 -0
  35. data/lib/bwapi/client/projects/queries/date_range.rb +67 -0
  36. data/lib/bwapi/client/projects/queries/mentions.rb +53 -0
  37. data/lib/bwapi/client/projects/query_groups.rb +70 -0
  38. data/lib/bwapi/client/projects/sharing.rb +57 -0
  39. data/lib/bwapi/client/projects/signals.rb +39 -0
  40. data/lib/bwapi/client/projects/summary.rb +21 -0
  41. data/lib/bwapi/client/projects/tags.rb +61 -0
  42. data/lib/bwapi/client/projects/users.rb +17 -0
  43. data/lib/bwapi/client/projects/workflow.rb +17 -0
  44. data/lib/bwapi/client/query_validation.rb +27 -0
  45. data/lib/bwapi/client/sso.rb +18 -0
  46. data/lib/bwapi/client/test_search.rb +14 -0
  47. data/lib/bwapi/client/user.rb +58 -0
  48. data/lib/bwapi/client/user/notifications.rb +36 -0
  49. data/lib/bwapi/configuration.rb +59 -0
  50. data/lib/bwapi/connection.rb +33 -0
  51. data/lib/bwapi/error.rb +42 -0
  52. data/lib/bwapi/request.rb +93 -0
  53. data/lib/bwapi/version.rb +3 -0
  54. data/lib/faraday/response/brandwatch_error.rb +25 -0
  55. data/lib/faraday/utils/utils.rb +25 -0
  56. data/spec/bwapi/authentication_spec.rb +57 -0
  57. data/spec/bwapi/client_spec.rb +205 -0
  58. data/spec/bwapi_spec.rb +23 -0
  59. data/spec/fixtures/.netrc +3 -0
  60. data/spec/helper.rb +12 -0
  61. metadata +178 -0
@@ -0,0 +1,14 @@
1
+ module BWAPI
2
+ class Client
3
+ module TestSearch
4
+
5
+ # TODO: Uncomment once the endpoint has been fixed
6
+ # Retrieve full text for a given url
7
+ #def test_search_content opts
8
+ # get "testsearch/content", opts
9
+ #end
10
+ #alias :test_search :test_search_content
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,58 @@
1
+ require 'bwapi/client/user/notifications'
2
+
3
+ module BWAPI
4
+ class Client
5
+ module User
6
+
7
+ # Get the current user
8
+ #
9
+ # @return [Hashie::Mash] User information
10
+ def user
11
+ get "user"
12
+ end
13
+
14
+ # Update the current user
15
+ #
16
+ # @param opts [Hash] options Hash of parameters
17
+ # @option opts [Integer] id Id of the user
18
+ # @option opts [Hash] tags The users assigned tags
19
+ # @option opts [String] passwordConfirmation The confirmed password
20
+ # @option opts [Boolean] enabled The status of the user
21
+ # @option opts [String] lastName The last name of the user
22
+ # @option opts [String] phone The users phone number
23
+ # @option opts [String] department The users department
24
+ # @option opts [String] job The users job
25
+ # @option opts [String] messenger The users IM details
26
+ # @option opts [String] password The password of the user
27
+ # @option opts [Integer] clientId The users client id
28
+ # @option opts [String] username The users username
29
+ # @option opts [String] address The users address
30
+ # @option opts [String] uiRole The users ui role
31
+ # @option opts [Array] apiRole The users api role
32
+ # @option opts [String] firstName The users first name
33
+ # @option opts [String] mobile The users mobile number
34
+ # @option opts [Date] creationDate Date the user was created on
35
+ # @return [Hashie::Mash] Updated user information
36
+ def update_user opts
37
+ put "user", opts
38
+ end
39
+
40
+ # Get users api role
41
+ #
42
+ # @return [String] Users api role
43
+ def api_role
44
+ user.apiRole
45
+ end
46
+
47
+ # Get users ui role
48
+ #
49
+ # @return [String] Users ui role
50
+ def ui_role
51
+ user.uiRole
52
+ end
53
+
54
+ include BWAPI::Client::User::Notifications
55
+
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,36 @@
1
+ module BWAPI
2
+ class Client
3
+ module User
4
+ module Notifications
5
+
6
+ # Get the current user notifications
7
+ #
8
+ # @param opts [Hash] options hash of parameters
9
+ # @option opts [Integer] page Page of projects to retrieve
10
+ # @option opts [Integer] pageSize Results per page of results
11
+ # @return [Hashie::Mash] User notifications
12
+ def notifications opts={}
13
+ get "user/notifications", opts
14
+ end
15
+
16
+ # Update users existing notifications
17
+ #
18
+ # @param opts [Hash] options Hash of parameters
19
+ # @option opts [Array] list User notifications to be edited
20
+ # @return [Hashie::Mash] Updated user notifications
21
+ def update_notification opts
22
+ put "user/notifications", opts
23
+ end
24
+
25
+ # Delete a users existing notification
26
+ #
27
+ # @param notification_id [Integer] Id of notification
28
+ # @return [Hashie::Mash] Deleted user notifications
29
+ def delete_notification notification_id
30
+ delete "user/notifications/#{notification_id}"
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,59 @@
1
+ require 'faraday'
2
+
3
+ module BWAPI
4
+ module Configuration
5
+
6
+ OPTION_KEYS = [
7
+ :api_endpoint,
8
+ :user_agent,
9
+ :adapter,
10
+ :username,
11
+ :password,
12
+ :grant_type,
13
+ :access_token,
14
+ :refresh_token,
15
+ :expires_in,
16
+ :client_id,
17
+ :client_secret,
18
+ :netrc,
19
+ :netrc_file
20
+ ].freeze
21
+
22
+ DEFAULT_ADAPTER = Faraday.default_adapter
23
+ DEFAULT_API_ENDPOINT = ENV['BWAPI_API_ENDPOINT'] || 'http://newapi.brandwatch.com/'
24
+ DEFAULT_CLIENT_ID = 'brandwatch-api-client'
25
+ DEFAULT_USER_AGENT = "BWAPI Ruby Gem #{BWAPI::VERSION}".freeze
26
+ DEFAULT_NETRC_FILE = File.join(ENV['HOME'], '.netrc')
27
+
28
+ attr_accessor *OPTION_KEYS
29
+
30
+ # Extend hook
31
+ def self.extended(base)
32
+ base.reset
33
+ end
34
+
35
+ def configure
36
+ yield self
37
+ end
38
+
39
+ # Convert option_keys to hash and return
40
+ def options
41
+ OPTION_KEYS.inject({}){|o,k|o.merge!(k => send(k))}
42
+ end
43
+
44
+ def reset
45
+ self.adapter = DEFAULT_ADAPTER
46
+ self.user_agent = DEFAULT_USER_AGENT
47
+ self.api_endpoint = DEFAULT_API_ENDPOINT
48
+ self.username = nil
49
+ self.password = nil
50
+ self.grant_type = nil
51
+ self.access_token = nil
52
+ self.refresh_token = nil
53
+ self.client_id = DEFAULT_CLIENT_ID
54
+ self.client_secret = nil
55
+ self.netrc = false
56
+ self.netrc_file = DEFAULT_NETRC_FILE
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,33 @@
1
+ require 'faraday_middleware'
2
+ require 'faraday/response/brandwatch_error'
3
+ require 'faraday/utils/utils'
4
+
5
+ module BWAPI
6
+ module Connection
7
+ private
8
+
9
+ # Create a connection to send request
10
+ def connection opts={}
11
+ connection = Faraday.new(opts) do |conn|
12
+
13
+ if opts[:force_urlencoded]
14
+ conn.request :url_encoded
15
+ else
16
+ conn.request :json
17
+ end
18
+
19
+ conn.request :json
20
+ conn.use Faraday::Response::BrandwatchError
21
+ conn.use FaradayMiddleware::FollowRedirects
22
+ conn.use FaradayMiddleware::Mashify
23
+ conn.use FaradayMiddleware::ParseJson, :content_type => /\bjson$/
24
+ conn.adapter adapter
25
+ end
26
+
27
+ connection.headers[:user_agent] = user_agent
28
+
29
+ connection
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,42 @@
1
+ module BWAPI
2
+
3
+ # BW error class to capture BWAPI error responses
4
+ class BWError < StandardError
5
+ def initialize(response=nil)
6
+ super()
7
+ end
8
+ end
9
+
10
+ # Raised when Brandwatch returns a 400 HTTP status code
11
+ class BadRequest < BWError; end
12
+
13
+ # Raised when Brandwatch returns a 401 HTTP status code
14
+ class Unauthorized < BWError; end
15
+
16
+ # Raised when Brandwatch returns a 403 HTTP status code
17
+ class Forbidden < BWError; end
18
+
19
+ # Raised when Brandwatch returns a 404 HTTP status code
20
+ class NotFound < BWError; end
21
+
22
+ # Raised when Brandwatch returns a 406 HTTP status code
23
+ class NotAcceptable < BWError; end
24
+
25
+ # Raised when Brandwatch returns a 422 HTTP status code
26
+ class UnprocessableEntity < BWError; end
27
+
28
+ # Raised when Brandwatch returns a 429 HTTP status code
29
+ class TooManyRequests < BWError; end
30
+
31
+ # Raised when Brandwatch returns a 500 HTTP status code
32
+ class InternalServerError < BWError; end
33
+
34
+ # Raised when Brandwatch returns a 501 HTTP status code
35
+ class NotImplemented < BWError; end
36
+
37
+ # Raised when Brandwatch returns a 502 HTTP status code
38
+ class BadGateway < BWError; end
39
+
40
+ # Raised when Brandwatch returns a 503 HTTP status code
41
+ class ServiceUnavailable < BWError; end
42
+ end
@@ -0,0 +1,93 @@
1
+ require 'multi_json'
2
+
3
+ module BWAPI
4
+ module Request
5
+
6
+ # Perform a get request
7
+ #
8
+ # @param path [String] URL path to send request
9
+ # @param opts [Hash] Request parameters
10
+ # @return [Hashie::Mash] Response body
11
+ def get path, opts={}
12
+ request(:get, path, opts).body
13
+ end
14
+
15
+ # Perform a delete request
16
+ #
17
+ # @param path [String] URL path to send request
18
+ # @param opts [Hash] Request parameters
19
+ # @return [Hashie::Mash] Response body
20
+ def delete path, opts={}
21
+ request(:delete, path, opts).body
22
+ end
23
+
24
+ # Perform a post request
25
+ #
26
+ # @param path [String] URL path to send request
27
+ # @param opts [Hash] Request parameters
28
+ # @return [Hashie::Mash] Response body
29
+ def post path, opts={}
30
+ request(:post, path, opts).body
31
+ end
32
+
33
+ # Perform a put request
34
+ #
35
+ # @param path [String] URL path to send request
36
+ # @param opts [Hash] Request parameters
37
+ # @return [Hashie::Mash] Response body
38
+ def put path, opts={}
39
+ request(:put, path, opts).body
40
+ end
41
+
42
+ # Perform a patch request
43
+ #
44
+ # @param path [String] URL path to send request
45
+ # @param opts [Hash] Request parameters
46
+ # @return [Hashie::Mash] Response body
47
+ def patch path, opts={}
48
+ request(:patch, path, opts).body
49
+ end
50
+
51
+ private
52
+
53
+ # Perform a request
54
+ #
55
+ # @param method [String] Type of request path
56
+ # @param path [String] URL path to send request
57
+ # @param opts [Hash] Request parameters
58
+ # @return [Hashie::Mash] Response
59
+ def request method, path, opts={}
60
+ token = access_token
61
+
62
+ force_urlencoded = opts.delete(:force_urlencoded) || false
63
+
64
+ conn_opts = {
65
+ :force_urlencoded => force_urlencoded,
66
+ :url => api_endpoint
67
+ }
68
+
69
+ response = connection(conn_opts).send(method) do |request|
70
+ # Add token to the header
71
+ if token
72
+ request.headers[:authorization] = "bearer #{token}"
73
+ end
74
+
75
+ case method
76
+ when :get
77
+ request.url path, opts
78
+ when :delete
79
+ request.url path, opts
80
+ when :patch, :post, :put
81
+ if force_urlencoded
82
+ request.url path, opts
83
+ else
84
+ request.path = path
85
+ request.body = MultiJson.dump(opts) unless opts.empty?
86
+ end
87
+ end
88
+ end
89
+
90
+ response
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,3 @@
1
+ module BWAPI
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,25 @@
1
+ require 'faraday'
2
+ require 'multi_json'
3
+
4
+ module Faraday
5
+ class Response::BrandwatchError < Response::Middleware
6
+ ERROR_MAP = {
7
+ 400 => BWAPI::BadRequest,
8
+ 401 => BWAPI::Unauthorized,
9
+ 403 => BWAPI::Forbidden,
10
+ 404 => BWAPI::NotFound,
11
+ 406 => BWAPI::NotAcceptable,
12
+ 422 => BWAPI::UnprocessableEntity,
13
+ 429 => BWAPI::TooManyRequests,
14
+ 500 => BWAPI::InternalServerError,
15
+ 501 => BWAPI::NotImplemented,
16
+ 502 => BWAPI::BadGateway,
17
+ 503 => BWAPI::ServiceUnavailable
18
+ }
19
+
20
+ def on_complete(response)
21
+ key = response[:status].to_i
22
+ raise ERROR_MAP[key].new(response) if ERROR_MAP.has_key? key
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ require 'faraday'
2
+
3
+ # TODO: Remove this patch once latest faraday rc has been released
4
+ # https://github.com/lostisland/faraday/issues/182#issuecomment-19518167
5
+ module Faraday
6
+ module Utils
7
+ def build_nested_query(value, prefix = nil)
8
+ case value
9
+ when Array
10
+ value.map { |v| build_nested_query(v, "#{prefix}") }.join("&")
11
+ #value.map { |v| build_nested_query(v, "#{prefix}%5B%5D") }.join("&")
12
+ when Hash
13
+ value.map { |k, v|
14
+ build_nested_query(v, prefix ? "#{prefix}#{escape(k)}" : escape(k))
15
+ #build_nested_query(v, prefix ? "#{prefix}%5B#{escape(k)}%5D" : escape(k))
16
+ }.join("&")
17
+ when NilClass
18
+ prefix
19
+ else
20
+ raise ArgumentError, "value must be a Hash" if prefix.nil?
21
+ "#{prefix}=#{escape(value)}"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,57 @@
1
+ require 'helper'
2
+
3
+ describe BWAPI::Authentication do
4
+
5
+ before do
6
+ BWAPI.reset
7
+ end
8
+
9
+ describe '.authenticated?' do
10
+ it 'returns true when authenticated' do
11
+ expect(BWAPI::Client.new.authenticated?).to eql(false)
12
+ end
13
+
14
+ it 'returns false when not authenticated' do
15
+ bw = BWAPI::Client.new :access_token => 'abcdef-ghijkl-123456-789012'
16
+ expect(bw.authenticated?).to eql(true)
17
+ end
18
+ end
19
+
20
+ describe '.application_client?' do
21
+ it 'returns true when client is a brandwatch-application-client' do
22
+ bw = BWAPI::Client.new :client_id => 'brandwatch-application-client'
23
+ expect(bw.application_client?).to eql(true)
24
+ end
25
+
26
+ it 'returns false when a client is not a brandwatch-application-client' do
27
+ expect(BWAPI::Client.new.application_client?).to eql(false)
28
+ end
29
+ end
30
+
31
+ describe '.api_client?' do
32
+ it 'returns true when client is a brandwatch-api-client' do
33
+ bw = BWAPI::Client.new :client_id => 'brandwatch-api-client'
34
+ expect(bw.api_client?).to eql(true)
35
+ end
36
+
37
+ it 'returns false when a client is not a brandwatch-api-client' do
38
+ bw = BWAPI::Client.new :client_id => 'brandwatch-application-client'
39
+ expect(bw.api_client?).to eql(false)
40
+ end
41
+ end
42
+
43
+ describe '.netrc_credentials' do
44
+ it 'returns nil when netrc is false' do
45
+ bw = BWAPI::Client.new
46
+ expect(bw.netrc_credentials).to eql(nil)
47
+ end
48
+
49
+ it 'returns credentials when netrc is true' do
50
+ bw = BWAPI::Client.new :netrc => true, :netrc_file => File.join(fixture_path, '.netrc')
51
+ bw.netrc_credentials
52
+ expect(bw.username).to eql('testuser@brandwatch.com')
53
+ expect(bw.password).to eql('password')
54
+ end
55
+
56
+ end
57
+ end