twingly-search 5.1.2 → 5.3.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ci-build-and-install-gem.yml +21 -0
  3. data/.github/workflows/ci.yml +27 -0
  4. data/CHANGELOG.md +58 -0
  5. data/README.md +18 -7
  6. data/examples/find_all_posts_mentioning_github.rb +8 -2
  7. data/lib/twingly/livefeed.rb +2 -0
  8. data/lib/twingly/livefeed/client.rb +5 -3
  9. data/lib/twingly/livefeed/error.rb +6 -1
  10. data/lib/twingly/livefeed/parser.rb +6 -3
  11. data/lib/twingly/livefeed/post.rb +34 -4
  12. data/lib/twingly/livefeed/result.rb +13 -9
  13. data/lib/twingly/livefeed/version.rb +3 -1
  14. data/lib/twingly/search.rb +2 -0
  15. data/lib/twingly/search/client.rb +4 -2
  16. data/lib/twingly/search/error.rb +12 -2
  17. data/lib/twingly/search/parser.rb +6 -3
  18. data/lib/twingly/search/post.rb +34 -4
  19. data/lib/twingly/search/query.rb +10 -3
  20. data/lib/twingly/search/result.rb +11 -5
  21. data/lib/twingly/search/version.rb +3 -1
  22. data/profiler/fixtures/vcr_cassettes/blog_livefeed_100.yml +43 -0
  23. data/profiler/fixtures/vcr_cassettes/blog_search_100.yml +43 -0
  24. data/profiler/profile_helper.rb +18 -0
  25. data/profiler/profile_livefeed.rb +21 -0
  26. data/profiler/profile_search.rb +23 -0
  27. data/spec/client_spec.rb +3 -3
  28. data/spec/error_spec.rb +4 -0
  29. data/spec/fixtures/unauthenticated_api_key_result.xml +3 -0
  30. data/spec/fixtures/unauthorized_api_key_result.xml +3 -3
  31. data/spec/fixtures/vcr_cassettes/search_for_spotify_on_sv_blogs.yml +1301 -565
  32. data/spec/livefeed/client_spec.rb +2 -2
  33. data/spec/livefeed/error_spec.rb +1 -0
  34. data/spec/livefeed/parser_spec.rb +3 -3
  35. data/spec/livefeed/post_spec.rb +47 -0
  36. data/spec/livefeed/result_spec.rb +22 -8
  37. data/spec/parser_spec.rb +11 -3
  38. data/spec/post_spec.rb +48 -0
  39. data/spec/query_spec.rb +6 -6
  40. data/spec/result_spec.rb +20 -6
  41. data/twingly-search-api-ruby.gemspec +8 -6
  42. metadata +60 -20
  43. data/.travis.yml +0 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3a75dac8aa30248ac63076961aed966d93bcb512
4
- data.tar.gz: 1c777949aa160f64333d2b70873b6c1bc73fd3e9
2
+ SHA256:
3
+ metadata.gz: f451d6c6e8102959e734c8376276e3d8a702155d7cd4e9e13e8b8d943310a7d4
4
+ data.tar.gz: 9b13fa23f12b24625b4f25a692e4c21c4fabb82e92e5fcefe24f5e85cb37129c
5
5
  SHA512:
6
- metadata.gz: 6311e1a9faa3dabbd1f517370ab2e5efadb736bdbfc20fe7d93480b930ebeb35471eebfb0d006c7d95097c4e70d78d9ea4de20aed30706edfbcfb66ebe8ab4b6
7
- data.tar.gz: 9fb8ec55a381bf78d234ec587e66893284187aee3a0960540a7a7f9675893218c35dae286df969f2595d0ca19510dcbf6f7b329f656fd216d82acde9d1b4e5a3
6
+ metadata.gz: 9564dd967b087fae002747d0425d3fc3afe27f351d77da2087bfdca4c3846e1c957dfb3995a429f2fff0a21a7584261adb26508844795de0642c417629ae2813
7
+ data.tar.gz: e369bac91125a4a89d1b1644325c251f25a11047638db92d42b45aef6b727dc6c0eb8fe1700d267914f0b02574648b79122d75b1efb912540cdc6a34375f1179
@@ -0,0 +1,21 @@
1
+ name: CI build and install gem
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-18.04
10
+
11
+ steps:
12
+ - name: Checkout code
13
+ uses: actions/checkout@v2
14
+
15
+ - name: Setup Ruby
16
+ uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: 2.7.2
19
+
20
+ - name: Build and install gem
21
+ run: gem build *.gemspec && gem install *.gem
@@ -0,0 +1,27 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ pull_request:
6
+
7
+ jobs:
8
+ build:
9
+ runs-on: ubuntu-18.04
10
+
11
+ strategy:
12
+ fail-fast: false
13
+ matrix:
14
+ ruby: [2.5.8, 2.6.6, 2.7.2, jruby-9.2.13.0]
15
+
16
+ steps:
17
+ - name: Checkout code
18
+ uses: actions/checkout@v2
19
+
20
+ - name: Setup Ruby ${{ matrix.ruby }}
21
+ uses: ruby/setup-ruby@v1
22
+ with:
23
+ ruby-version: ${{ matrix.ruby }}
24
+ bundler-cache: true
25
+
26
+ - name: Run tests
27
+ run: bundle exec rake
data/CHANGELOG.md CHANGED
@@ -1,5 +1,63 @@
1
1
  # Change Log
2
2
 
3
+ ## [v5.3.0](https://github.com/twingly/twingly-search-api-ruby/tree/v5.3.0) (2019-04-03)
4
+ [Full Changelog](https://github.com/twingly/twingly-search-api-ruby/compare/v5.2.0...v5.3.0)
5
+
6
+ **Implemented enhancements:**
7
+
8
+ - Differentiate between 401 and 402 status codes [\#80](https://github.com/twingly/twingly-search-api-ruby/issues/80)
9
+ - Low hanging fruit that would reduce memory consumption [\#75](https://github.com/twingly/twingly-search-api-ruby/issues/75)
10
+ - Add fixture for "Invalid language code\(s\)" [\#56](https://github.com/twingly/twingly-search-api-ruby/issues/56)
11
+
12
+ **Fixed bugs:**
13
+
14
+ - Inconsistent formating in Result\#inspect [\#79](https://github.com/twingly/twingly-search-api-ruby/issues/79)
15
+ - Uninitialized variable warnings [\#76](https://github.com/twingly/twingly-search-api-ruby/issues/76)
16
+
17
+ **Merged pull requests:**
18
+
19
+ - Drop support for older Rubies [\#87](https://github.com/twingly/twingly-search-api-ruby/pull/87) ([walro](https://github.com/walro))
20
+ - AuthError -\> AuthenticationError/AuthorizationError [\#86](https://github.com/twingly/twingly-search-api-ruby/pull/86) ([jage](https://github.com/jage))
21
+ - Travis for modern Rubies [\#85](https://github.com/twingly/twingly-search-api-ruby/pull/85) ([jage](https://github.com/jage))
22
+ - Profile for object allocation and pick some fruit [\#84](https://github.com/twingly/twingly-search-api-ruby/pull/84) ([jage](https://github.com/jage))
23
+ - Improve Result\#inspect output [\#83](https://github.com/twingly/twingly-search-api-ruby/pull/83) ([jage](https://github.com/jage))
24
+ - Initialize variables to avoid warnings [\#82](https://github.com/twingly/twingly-search-api-ruby/pull/82) ([jage](https://github.com/jage))
25
+ - Remove deprecated Query\#language usage in example [\#81](https://github.com/twingly/twingly-search-api-ruby/pull/81) ([jage](https://github.com/jage))
26
+
27
+ ## [v5.2.0](https://github.com/twingly/twingly-search-api-ruby/tree/v5.2.0) (2018-05-17)
28
+ [Full Changelog](https://github.com/twingly/twingly-search-api-ruby/compare/v5.1.4...v5.2.0)
29
+
30
+ **Merged pull requests:**
31
+
32
+ - Add Post\#to\_h for both LiveFeed and Search [\#77](https://github.com/twingly/twingly-search-api-ruby/pull/77) ([dentarg](https://github.com/dentarg))
33
+
34
+ ## [v5.1.4](https://github.com/twingly/twingly-search-api-ruby/tree/v5.1.4) (2018-02-23)
35
+ [Full Changelog](https://github.com/twingly/twingly-search-api-ruby/compare/v5.1.3...v5.1.4)
36
+
37
+ **Implemented enhancements:**
38
+
39
+ - Looser requirement on Faraday [\#70](https://github.com/twingly/twingly-search-api-ruby/issues/70)
40
+
41
+ **Fixed bugs:**
42
+
43
+ - Update yard gem dependency [\#72](https://github.com/twingly/twingly-search-api-ruby/issues/72)
44
+
45
+ **Merged pull requests:**
46
+
47
+ - Looser requirements on Faraday [\#74](https://github.com/twingly/twingly-search-api-ruby/pull/74) ([jage](https://github.com/jage))
48
+ - Test with latest Ruby versions [\#73](https://github.com/twingly/twingly-search-api-ruby/pull/73) ([dentarg](https://github.com/dentarg))
49
+ - Test with latest rubies, support Ruby 2.4 and JRuby 9.1 [\#71](https://github.com/twingly/twingly-search-api-ruby/pull/71) ([walro](https://github.com/walro))
50
+
51
+ ## [v5.1.3](https://github.com/twingly/twingly-search-api-ruby/tree/v5.1.3) (2017-10-16)
52
+ [Full Changelog](https://github.com/twingly/twingly-search-api-ruby/compare/v5.1.2...v5.1.3)
53
+
54
+ **Merged pull requests:**
55
+
56
+ - Revert "Include timezone info for timestamps in search query" [\#69](https://github.com/twingly/twingly-search-api-ruby/pull/69) ([walro](https://github.com/walro))
57
+
58
+ ## [v5.1.2](https://github.com/twingly/twingly-search-api-ruby/tree/v5.1.2) (2017-05-29)
59
+ [Full Changelog](https://github.com/twingly/twingly-search-api-ruby/compare/v5.1.1...v5.1.2)
60
+
3
61
  ## [v5.1.1](https://github.com/twingly/twingly-search-api-ruby/tree/v5.1.1) (2017-05-17)
4
62
  [Full Changelog](https://github.com/twingly/twingly-search-api-ruby/compare/v5.1.0...v5.1.1)
5
63
 
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Twingly Search API Ruby
2
2
 
3
- [![Build Status](https://travis-ci.org/twingly/twingly-search-api-ruby.png?branch=master)](https://travis-ci.org/twingly/twingly-search-api-ruby)
3
+ [![GitHub Build Status](https://github.com/twingly/twingly-search-api-ruby/workflows/CI/badge.svg?branch=master)](https://github.com/twingly/twingly-search-api-ruby/actions)
4
4
  [![Code Climate](https://codeclimate.com/github/twingly/twingly-search-api-ruby/badges/gpa.svg)](https://codeclimate.com/github/twingly/twingly-search-api-ruby)
5
5
 
6
6
  A Ruby gem for Twingly's Blog Search API (previously known as Analytics API) and Blog LiveFeed API. Twingly is a blog search service that provides a searchable API known as [Twingly Blog Search API][Blog Search API documentation] and a blog data firehose called [Twingly Blog LiveFeed API][Blog LiveFeed API documentation].
@@ -27,7 +27,7 @@ To learn more about the features of this gem, read the [gem documentation] or ch
27
27
 
28
28
  To learn more about the capabilities of Twingly's APIs, please read the [Blog Search API documentation] and [Blog LiveFeed API documentation].
29
29
 
30
- [gem documentation]: http://www.rubydoc.info/github/twingly/twingly-search-api-ruby
30
+ [gem documentation]: https://www.rubydoc.info/github/twingly/twingly-search-api-ruby
31
31
  [Blog Search API documentation]: https://developer.twingly.com/resources/search/
32
32
  [Blog LiveFeed API documentation]: https://developer.twingly.com/resources/livefeed/
33
33
 
@@ -46,7 +46,7 @@ query = client.query do |query|
46
46
  end
47
47
 
48
48
  result = query.execute
49
- => #<Twingly::Search::Result:0x3ff7adcbe3d4 @posts, @number_of_matches_returned=10, @number_of_matches_total=3035221>
49
+ => #<Twingly::Search::Result:0x3fca8ad3aa60 posts, number_of_matches_returned=10, number_of_matches_total=281, incomplete_result=false, seconds_elapsed=0.239, all_results_returned?=false, incomplete?=false>
50
50
  result.posts # will include all returned posts
51
51
  ```
52
52
 
@@ -64,7 +64,7 @@ end
64
64
 
65
65
  # get the next chunk of posts
66
66
  result = client.next_result
67
- => #<Twingly::LiveFeed::Result:0x3fcd98215c14 @posts, @ts=2017-04-18 14:42:18 UTC, @from=2017-04-18 13:42:06 UTC, @number_of_posts=989, @max_number_of_posts=1000, @first_post=2017-04-18 13:42:19 UTC, @last_post=2017-04-18 14:42:13 UTC>
67
+ => #<Twingly::LiveFeed::Result:0x3fca8ad4e81c posts, ts=2019-03-27 12:52:54 UTC, from=2019-03-27 11:52:53 UTC, number_of_posts=709, max_number_of_posts=1000, first_post=2019-03-27 11:53:02 UTC, last_post=2019-03-27 12:52:42 UTC, next_timestamp=2019-03-27 12:52:42 UTC>
68
68
 
69
69
  result.posts # will include all returned posts
70
70
  ```
@@ -73,8 +73,8 @@ result.posts # will include all returned posts
73
73
 
74
74
  * API key, [sign up](https://www.twingly.com/try-for-free) via [twingly.com](https://www.twingly.com/) to get one
75
75
  * Ruby
76
- * Ruby 2.1, 2.2, 2.3
77
- * JRuby 9000
76
+ * Ruby >= 2.5
77
+ * JRuby >= 9.2
78
78
 
79
79
  ## Development
80
80
 
@@ -88,9 +88,19 @@ Run the tests
88
88
 
89
89
  bundle exec rake
90
90
 
91
+ ### Profiling
92
+
93
+ It's possible to profile memory and object allocation:
94
+
95
+ bundle exec ruby profiler/profile_livefeed.rb
96
+ bundle exec ruby profiler/profile_search.rb
97
+
98
+ Currently using [memory_profiler](https://github.com/SamSaffron/memory_profiler) for reports and [VCR](https://github.com/vcr/vcr) for saving requests (to make runs comparable).
99
+
91
100
  ### Release
92
101
 
93
102
  1. Make a commit bumping the version in `lib/twingly/search/version.rb`, follow [Semantic Versioning 2.0.0](http://semver.org/). No need to push as this will be taken care of automatically in the next step.
103
+ 1. Ensure you are signed in to RubyGems.org as [twingly][twingly-rubygems] with `gem signin`.
94
104
  1. Build and the release gem with `bundle exec rake release`. This will create a git tag for the version and push the `.gem` file to [RubyGems.org].
95
105
  1. Generate a changelog with `github_changelog_generator` (`gem install github_changelog_generator` if you don't have it). Set `CHANGELOG_GITHUB_TOKEN` to a personal access token to increase the API rate limit. (The changelog uses [GitHub Changelog Generator](https://github.com/skywinder/github-changelog-generator/))
96
106
  1. Update release information on the [releases page]. This is done manually.
@@ -106,4 +116,5 @@ This gem is documented using [YARD]. To start a local YARD server run:
106
116
 
107
117
  The YARD server reloads the documentation automatically so there is no need to restart it when making changes.
108
118
 
109
- [YARD]: http://yardoc.org/
119
+ [YARD]: https://yardoc.org/
120
+ [twingly-rubygems]: https://rubygems.org/profiles/twingly
@@ -8,8 +8,14 @@ class SearchPostStream
8
8
  end
9
9
 
10
10
  @query = client.query do |query|
11
- query.language = language
12
- query.search_query = "sort-order:asc sort:published #{keyword}"
11
+ query_parts = [
12
+ "sort-order:asc",
13
+ "sort:published",
14
+ keyword,
15
+ ]
16
+ query_parts << "lang:#{language}" if language
17
+
18
+ query.search_query = query_parts.join(" ")
13
19
  end
14
20
  end
15
21
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "livefeed/version"
2
4
  require_relative "livefeed/error"
3
5
  require_relative "livefeed/client"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "faraday"
2
4
  require "time"
3
5
 
@@ -30,7 +32,7 @@ module Twingly
30
32
  # @option options [String] :max_posts the maximum number of posts that can
31
33
  # be returned for each request
32
34
  # @option options [String] :timestamp the timestamp to start the client at
33
- # @raise [AuthError] if an API key is not set
35
+ # @raise [AuthenticationError] if an API key is not set
34
36
  def initialize(api_key = nil, options = {})
35
37
  @api_key = api_key
36
38
  @user_agent = options.fetch(:user_agent) { DEFAULT_USER_AGENT }
@@ -49,7 +51,7 @@ module Twingly
49
51
  # then returns the result.
50
52
  #
51
53
  # @raise [QueryError] if the timestamp is invalid.
52
- # @raise [AuthError] if the API couldn't authenticate you. Make sure your API key is correct.
54
+ # @raise [AuthenticationError] if the API couldn't authenticate you. Make sure your API key is correct.
53
55
  # @raise [ServerError] if the query could not be executed due to a server error.
54
56
  # @return [Result] the result for this request.
55
57
  def next_result
@@ -110,7 +112,7 @@ module Twingly
110
112
  end
111
113
 
112
114
  def api_key_missing
113
- fail AuthError, "No API key has been provided."
115
+ fail AuthenticationError, "No API key has been provided."
114
116
  end
115
117
 
116
118
  def assert_valid_time(time)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Twingly
2
4
  module LiveFeed
3
5
  class Error < StandardError
@@ -7,7 +9,7 @@ module Twingly
7
9
  when /^400/, /^404/
8
10
  QueryError
9
11
  when /^401/
10
- AuthError
12
+ AuthenticationError
11
13
  else
12
14
  ServerError
13
15
  end
@@ -19,6 +21,9 @@ module Twingly
19
21
  class AuthError < Error
20
22
  end
21
23
 
24
+ class AuthenticationError < AuthError
25
+ end
26
+
22
27
  class ServerError < Error
23
28
  end
24
29
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'nokogiri'
2
4
 
3
5
  module Twingly
@@ -45,9 +47,10 @@ module Twingly
45
47
  def parse_post(element)
46
48
  post_params = {}
47
49
  element.element_children.each do |child|
48
- post_params[child.name] =
49
- case child.name
50
- when *%w(tags links images)
50
+ name = child.name.freeze
51
+ post_params[name] =
52
+ case name
53
+ when "tags", "links", "images"
51
54
  parse_array(child)
52
55
  when "coordinates"
53
56
  parse_coordinates(child)
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ # frozen_string_literal: true
2
3
 
3
4
  module Twingly
4
5
  module LiveFeed
@@ -36,6 +37,9 @@ module Twingly
36
37
  :published_at, :reindexed_at, :inlinks_count, :blog_id, :blog_name,
37
38
  :blog_url, :blog_rank, :authority
38
39
 
40
+ EMPTY_ARRAY = [].freeze
41
+ EMPTY_HASH = {}.freeze
42
+
39
43
  # Sets all instance variables for the {Post}, given a Hash.
40
44
  #
41
45
  # @param [Hash] params containing blog post data.
@@ -47,10 +51,10 @@ module Twingly
47
51
  @text = params.fetch('text')
48
52
  @language_code = params.fetch('languageCode')
49
53
  @location_code = params.fetch('locationCode')
50
- @coordinates = params.fetch('coordinates', {})
51
- @links = params.fetch('links', [])
52
- @tags = params.fetch('tags', [])
53
- @images = params.fetch('images', [])
54
+ @coordinates = params.fetch('coordinates') { EMPTY_HASH }
55
+ @links = params.fetch('links') { EMPTY_ARRAY }
56
+ @tags = params.fetch('tags') { EMPTY_ARRAY }
57
+ @images = params.fetch('images') { EMPTY_ARRAY }
54
58
  @indexed_at = Time.parse(params.fetch('indexedAt'))
55
59
  @published_at = Time.parse(params.fetch('publishedAt'))
56
60
  @reindexed_at = Time.parse(params.fetch('reindexedAt'))
@@ -61,6 +65,32 @@ module Twingly
61
65
  @blog_rank = params.fetch('blogRank').to_i
62
66
  @authority = params.fetch('authority').to_i
63
67
  end
68
+
69
+ # @return [Hash] a hash containing all post attributes.
70
+ def to_h
71
+ {
72
+ id: @id,
73
+ author: @author,
74
+ url: @url,
75
+ title: @title,
76
+ text: @text,
77
+ language_code: @language_code,
78
+ location_code: @location_code,
79
+ coordinates: @coordinates,
80
+ links: @links,
81
+ tags: @tags,
82
+ images: @images,
83
+ indexed_at: @indexed_at,
84
+ published_at: @published_at,
85
+ reindexed_at: @reindexed_at,
86
+ inlinks_count: @inlinks_count,
87
+ blog_id: @blog_id,
88
+ blog_name: @blog_name,
89
+ blog_url: @blog_url,
90
+ blog_rank: @blog_rank,
91
+ authority: @authority,
92
+ }
93
+ end
64
94
  end
65
95
  end
66
96
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Twingly
2
4
  module LiveFeed
3
5
  # Represents a result from a request to the LiveFeed API
@@ -23,16 +25,18 @@ module Twingly
23
25
  end
24
26
 
25
27
  def inspect
26
- instance_variables = "@posts, "
27
- instance_variables << "@ts=#{self.ts}, "
28
- instance_variables << "@from=#{self.from}, "
29
- instance_variables << "@number_of_posts=#{self.number_of_posts}, "
30
- instance_variables << "@max_number_of_posts=#{self.max_number_of_posts}, "
31
- instance_variables << "@first_post=#{self.first_post}, "
32
- instance_variables << "@last_post=#{self.last_post}"
33
- instance_variables << "@next_timestamp=#{self.next_timestamp}"
28
+ instance_methods = [
29
+ "posts",
30
+ "ts=#{self.ts}",
31
+ "from=#{self.from}",
32
+ "number_of_posts=#{self.number_of_posts}",
33
+ "max_number_of_posts=#{self.max_number_of_posts}",
34
+ "first_post=#{self.first_post}",
35
+ "last_post=#{self.last_post}",
36
+ "next_timestamp=#{self.next_timestamp}",
37
+ ].join(", ")
34
38
 
35
- sprintf("#<%s:0x%x %s>", self.class.name, __id__, instance_variables)
39
+ sprintf("#<%s:0x%x %s>", self.class.name, __id__, instance_methods)
36
40
  end
37
41
  end
38
42
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Twingly
2
4
  module LiveFeed
3
- VERSION = "5.0.1"
5
+ VERSION = "5.3.0"
4
6
  end
5
7
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "search/version"
2
4
  require_relative "search/error"
3
5
  require_relative "search/client"
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "faraday"
2
4
 
3
5
  module Twingly
@@ -19,7 +21,7 @@ module Twingly
19
21
  # @param options [Hash]
20
22
  # @option options [String] :user_agent the user agent to be used
21
23
  # for all requests
22
- # @raise [AuthError] if an API key is not set.
24
+ # @raise [AuthenticationError] if an API key is not set.
23
25
  def initialize(api_key = nil, options = {})
24
26
  @api_key = api_key
25
27
  @user_agent = options.fetch(:user_agent) { DEFAULT_USER_AGENT }
@@ -70,7 +72,7 @@ module Twingly
70
72
  end
71
73
 
72
74
  def api_key_missing
73
- fail AuthError, "No API key has been provided."
75
+ fail AuthenticationError, "No API key has been provided."
74
76
  end
75
77
  end
76
78
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Twingly
2
4
  module Search
3
5
  class Error < StandardError
@@ -6,8 +8,10 @@ module Twingly
6
8
  case code.to_s
7
9
  when /^400/, /^404/
8
10
  QueryError
9
- when /^401/, /^402/
10
- AuthError
11
+ when /^401/ # E.g. API key not enabled
12
+ AuthenticationError
13
+ when /^402/ # E.g. language access denied
14
+ AuthorizationError
11
15
  else
12
16
  ServerError
13
17
  end
@@ -19,6 +23,12 @@ module Twingly
19
23
  class AuthError < Error
20
24
  end
21
25
 
26
+ class AuthenticationError < AuthError
27
+ end
28
+
29
+ class AuthorizationError < AuthError
30
+ end
31
+
22
32
  class ServerError < Error
23
33
  end
24
34