metonym 1.0.0 → 1.0.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.
@@ -1,8 +1,18 @@
1
- require "metonym/version"
1
+ # frozen_string_literal: true
2
+
3
+ require 'metonym/version'
2
4
  require 'date'
3
5
  require 'net/http'
4
6
  require 'metonym/lib/gnews.rb'
5
- require 'metonym/lib/validate.rb'
7
+ require 'metonym/lib/presenters/base_response_presenter.rb'
8
+ require 'metonym/lib/presenters/gnews_response_presenter.rb'
9
+ require 'metonym/lib/presenters/news_api_response_presenter.rb'
10
+ require 'metonym/lib/repositories/base_repository.rb'
11
+ require 'metonym/lib/repositories/gnews_repository.rb'
12
+ require 'metonym/lib/repositories/news_api_repository.rb'
13
+ require 'metonym/lib/validators/base_validator.rb'
14
+ require 'metonym/lib/validators/gnews_query_validator.rb'
15
+ require 'metonym/lib/validators/news_api_query_validator.rb'
6
16
  require 'metonym/lib/news_api.rb'
7
17
  require 'byebug'
8
18
  require 'json'
@@ -1,49 +1,51 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Gnews
2
- class Query
3
- attr_accessor :gnews_api_key
4
- attr_accessor :gnews_version
5
- attr_accessor :uri
6
-
7
- def initialize(key, version = nil)
8
- @gnews_api_key = key
9
- @gnews_version = version.nil? ? 'v2' : version
10
- @uri = URI("https://gnews.io/api/#{@gnews_version}/")
11
- end
12
-
13
- def search(args, format = 'json')
14
- begin
15
- v = Validate::GnewsValidator.new
16
- raise "API Key is required" if v.is_key_present?(@gnews_api_key) == false
17
- raise "Invalid parameter sequence" if v.is_query_valid?(args) == false
18
- raise "Invalid country sent" if v.is_country_valid?(args) == false
19
- raise "Invalid language sent" if v.is_language_valid?(args) == false
20
- raise "Invalid date or dates sent" if v.is_date_valid?(args) == false
21
- raise "Invalid format sent" if v.is_format_valid?(format) == false
22
-
23
- args = prepare_arguments(args)
24
- @uri.query = URI.encode_www_form(args)
25
- response = Net::HTTP.get_response(@uri)
26
- rescue Exception => e
27
- response = {"errors" => e.to_s}
28
- ensure
29
- if response.is_a?(Hash) && response.has_key?('errors')
30
- return response
31
- else
32
- if format.nil? || format == 'json'
33
- return response.body
34
- elsif format == 'hash'
35
- return JSON.parse(response.body)
36
- end
37
- end
38
- end
39
- end
40
-
41
- private
42
- def prepare_arguments(args)
43
- args['mindate'] = args.has_key?('mindate') ? args['mindate'].strftime("%y-%m-%d") : nil
44
- args['maxdate'] = args.has_key?('maxdate') ? args['maxdate'].strftime("%y-%m-%d") : nil
45
- args["token"] = @gnews_api_key
46
- args
47
- end
4
+ class Query
5
+ attr_accessor :gnews_api_key
6
+ attr_accessor :uri
7
+
8
+ def initialize(key)
9
+ @gnews_api_key = key
10
+ @gnews = Gnews::GnewsRepository.new(key)
11
+ end
12
+
13
+ def search(args, **options)
14
+ request('search', args: args, format: define_response_format(options))
15
+ end
16
+
17
+ def top_news(args, **options)
18
+ request('top-news', args: args, format: define_response_format(options))
19
+ end
20
+
21
+ private
22
+
23
+ def define_response_format(options)
24
+ options[:format] || 'json'
25
+ end
26
+
27
+ def request(resource, args:, format:)
28
+ validate_query_parameters(args, format)
29
+
30
+ case resource
31
+ when 'search'
32
+ response = @gnews.search(query: args)
33
+ when 'top-news'
34
+ response = @gnews.top_news(query: args)
35
+ when 'topics'
36
+ response = @gnews.topics(query: args)
37
+ end
38
+ rescue StandardError => e
39
+ response = { errors: e.to_s }
40
+ ensure
41
+ presenter = Gnews::GnewsResponsePresenter.new
42
+ return presenter.generate_formatted_response(response, format)
43
+ end
44
+
45
+ def validate_query_parameters(args, format)
46
+ v = Validate::GnewsQueryValidator.new(@gnews_api_key,
47
+ args: args, format: format)
48
+ raise v unless v
48
49
  end
49
- end
50
+ end
51
+ end
@@ -1,65 +1,54 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module NewsApi
2
- class Query
3
- attr_accessor :news_api_key
4
- attr_accessor :news_api_version
5
- attr_accessor :uri
4
+ class Query
5
+ attr_accessor :news_api_key
6
+ attr_accessor :uri
6
7
 
7
- def initialize(key, version = nil)
8
- @news_api_key = key
9
- @news_api_version = version.nil? ? 'v2' : version
10
- @uri = "https://newsapi.org/#{@news_api_version}"
11
- end
8
+ def initialize(key)
9
+ @news_api_key = key
10
+ @news_api = NewsApi::NewsApiRepository.new(key)
11
+ end
12
12
 
13
- def top_headlines(args, format = 'json')
14
- uri = URI("#{@uri}/top-headlines")
15
- return request(args, format, uri, 'top-headlines')
16
- end
13
+ def everything(args, **options)
14
+ request('everything', args: args, format: define_response_format(options))
15
+ end
17
16
 
18
- def everything(args, format = 'json')
19
- uri = URI("#{@uri}/everything")
20
- return request(args, format, uri, 'everything')
21
- end
17
+ def top_headlines(args, **options)
18
+ request('top-headlines', args: args, format: define_response_format(options))
19
+ end
22
20
 
23
- def sources(args, format = 'json')
24
- uri = URI("#{@uri}/sources")
25
- return request(args, format, uri, 'sources')
26
- end
21
+ def sources(args, **options)
22
+ request('sources', args: args, format: define_response_format(options))
23
+ end
27
24
 
28
- private
29
- def request(args, format, uri, endpoint)
30
- begin
31
- v = Validate::NewsApiValidator.new
32
- raise "API Key is required" if v.is_key_present?(@news_api_key) == false
33
- raise "Invalid parameter sequence" if v.is_query_valid?(args, endpoint) == false
34
- raise "Invalid country sent" if v.is_country_valid?(args) == false
35
- raise "Invalid language sent" if v.is_language_valid?(args) == false
36
- raise "Invalid date or dates sent" if v.is_date_valid?(args) == false
37
- raise "Invalid format sent" if v.is_format_valid?(format) == false
38
-
39
- args = prepare_arguments(args)
25
+ private
40
26
 
41
- uri.query = URI.encode_www_form(args)
42
- response = Net::HTTP.get_response(uri)
43
- rescue Exception => e
44
- response = {"errors" => e.to_s}
45
- ensure
46
- if response.is_a?(Hash) && response.has_key?('errors')
47
- return response
48
- else
49
- if format.nil? || format == 'json'
50
- return response.body
51
- elsif format == 'hash'
52
- return JSON.parse(response.body)
53
- end
54
- end
55
- end
56
- end
27
+ def define_response_format(options)
28
+ options[:format] || 'json'
29
+ end
30
+
31
+ def request(resource, args:, format:)
32
+ validate_query_parameters(args, format, resource)
33
+
34
+ case resource
35
+ when 'top-headlines'
36
+ response = @news_api.top_headlines(query: args)
37
+ when 'everything'
38
+ response = @news_api.everything(query: args)
39
+ when 'sources'
40
+ response = @news_api.sources(query: args)
41
+ end
42
+ rescue StandardError => e
43
+ response = { errors: e.to_s }
44
+ ensure
45
+ presenter = NewsApi::NewsApiResponsePresenter.new
46
+ return presenter.generate_formatted_response(response, format)
47
+ end
57
48
 
58
- def prepare_arguments(args)
59
- args['apiKey'] = @news_api_key
60
- args['from'] = args.has_key?('from') ? args['from'].strftime("%FT%T%:z") : nil
61
- args['to'] = args.has_key?('to') ? args['to'].strftime("%FT%T%:z") : nil
62
- args
63
- end
49
+ def validate_query_parameters(args, format, resource)
50
+ v = Validate::NewsApiQueryValidator.new(@news_api_key, args: args, format: format, endpoint: resource)
51
+ raise v unless v
64
52
  end
65
- end
53
+ end
54
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class BaseResponsePresenter
4
+ def generate_formatted_response(response, format)
5
+ return response if response.is_a?(Hash) && response.key?(:errors)
6
+
7
+ case format
8
+ when nil
9
+ response.body
10
+ when 'json'
11
+ response.body
12
+ when 'hash'
13
+ JSON.parse(response.body)
14
+ else
15
+ response.body
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gnews
4
+ class GnewsResponsePresenter < BaseResponsePresenter; end
5
+ end
@@ -0,0 +1,3 @@
1
+ module NewsApi
2
+ class NewsApiResponsePresenter < BaseResponsePresenter; end
3
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class BaseRepository
4
+ def request(uri, query:, resource:)
5
+ uri = URI(uri += resource)
6
+ uri.query = URI.encode_www_form(prepare_arguments(query))
7
+ Net::HTTP.get_response(uri)
8
+ end
9
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gnews
4
+ class GnewsRepository < BaseRepository
5
+ def initialize(api_key)
6
+ @gnews_api_key = api_key
7
+ @uri = 'https://gnews.io/api/v3/'
8
+ end
9
+
10
+ def search(query:)
11
+ request(@uri, query: query, resource: 'search')
12
+ end
13
+
14
+ def top_news(query:)
15
+ request(@uri, query: query, resource: 'top-news')
16
+ end
17
+
18
+ def topic
19
+ request(@uri, query: query, resource: 'topic')
20
+ end
21
+
22
+ private
23
+
24
+ def prepare_arguments(query)
25
+ query['mindate'] = query.key?(:mindate) ? query[:mindate].strftime('%y-%m-%d') : nil
26
+ query['maxdate'] = query.key?(:maxdate) ? query[:maxdate].strftime('%y-%m-%d') : nil
27
+ query['token'] = @gnews_api_key
28
+ query
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NewsApi
4
+ class NewsApiRepository < BaseRepository
5
+ def initialize(api_key)
6
+ @news_api_key = api_key
7
+ @uri = 'https://newsapi.org/v2/'
8
+ end
9
+
10
+ def everything(query:)
11
+ request(@uri, query: query, resource: 'everything')
12
+ end
13
+
14
+ def top_headlines(query:)
15
+ request(@uri, query: query, resource: 'top-headlines')
16
+ end
17
+
18
+ def sources(query:)
19
+ request(@uri, query: query, resource: 'sources')
20
+ end
21
+
22
+ private
23
+
24
+ def prepare_arguments(query)
25
+ query['from'] = query.key?(:from) ? query[:from].strftime('%FT%T%:z') : nil
26
+ query['to'] = query.key?(:to) ? query[:to].strftime('%FT%T%:z') : nil
27
+ query['apiKey'] = @news_api_key
28
+ query
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Validate
4
+ class BaseValidator
5
+ protected
6
+
7
+ def key_present?(args)
8
+ !args.nil?
9
+ end
10
+
11
+ def language_valid?(args)
12
+ return true if args[:lang].nil?
13
+
14
+ [
15
+ 'af', 'ak', 'sq', 'am', 'ar', 'hy', 'az', 'eu', 'be', 'bem', 'bn', 'bs', 'bh', 'br', 'bg', 'km', 'ca', 'chr', 'ny', 'zh-CN',
16
+ 'zh-TW', 'co', 'hr', 'cs', 'da', 'nl', 'en', 'eo', 'et', 'ee', 'fo', 'tl', 'fi', 'fr', 'fy', 'gl', 'ka', 'de', 'el', 'gn', 'gu',
17
+ 'ht', 'ha', 'haw', 'iw', 'hi', 'hu', 'is', 'ig', 'id', 'ia', 'ga', 'it', 'ja', 'jw', 'kn', 'kk', 'rw', 'rn', 'kg', 'ko', 'kri',
18
+ 'ku', 'ckb', 'ky', 'lo', 'la', 'lv', 'ln', 'lt', 'loz', 'lg', 'ach', 'mk', 'mg', 'ms', 'ml', 'mt', 'mi', 'mr', 'mfe', 'mo', 'mn',
19
+ 'sr-ME', 'ne', 'nso', 'no', 'nn', 'oc', 'or', 'om', 'ps', 'fa', 'pl', 'pt-BR', 'pt-PT', 'pa', 'qu', 'ro', 'rm', 'nyn', 'ru', 'gd',
20
+ 'sr', 'sh', 'st', 'tn', 'crs', 'sn', 'sd', 'si', 'sk', 'sl', 'so', 'es', 'sp-419', 'su', 'sw', 'sv', 'tg', 'ta', 'tt', 'te', 'th', 'ti',
21
+ 'to', 'lua', 'tum', 'tr', 'tk', 'tw', 'ug', 'uk', 'ur', 'uz', 'vi', 'cy', 'wo', 'xh', 'yi', 'yo', 'zu'
22
+ ].include?(args[:lang].downcase)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Validate
4
+ class GnewsQueryValidator < BaseValidator
5
+ COUNTRIES = %w[
6
+ af al dz as ad ao ai aq ag ar am aw au at az bs bh bd bb by
7
+ be bz bj bm bt bo ba bw bv br io bn bg bf bi kh cm ca cv ky
8
+ cf td cl cn cx cc co km cg cd ck cr ci hr cu cy cz dk dj dm
9
+ do ec eg sv gq er ee et fk fo fj fi fr gf pf tf ga gm ge de
10
+ gh gi gr gl gd gp gu gt gn gw gy ht hm va hn hk hu is in id
11
+ ir iq ie il it jm jp jo kz ke ki kp kr kw kg la lv lb ls lr
12
+ ly li lt lu mo mk mg mw my mv ml mt mh mq mr mu yt mx fm md
13
+ mc mn ms ma mz mm na nr np nl an nc nz ni ne ng nu nf mp no
14
+ om pk pw ps pa pg py pe ph pn pl pt pr qa re ro ru rw sh kn
15
+ lc pm vc ws sm st sa sn cs sc sl sg sk si sb so za gs sp lk
16
+ sd sr sj sz se ch sy tw tj tz th tl tg tk to tt tn tr tm tc
17
+ tv ug ua ae uk us um uy uz vu ve vn vg vi wf eh ye zm zw
18
+ ].freeze
19
+
20
+ def initialize(api_key, args:, format:)
21
+ raise 'API Key is required' unless key_present?(api_key)
22
+ raise 'Invalid parameter sequence' unless query_valid?(args)
23
+ raise 'Invalid country sent' unless country_valid?(args)
24
+ raise 'Invalid language sent' unless language_valid?(args)
25
+ raise 'Invalid date or dates sent' unless date_valid?(args)
26
+
27
+ true
28
+ end
29
+
30
+ private
31
+
32
+ def query_valid?(args)
33
+ search_template = %i[q max lang country mindate maxdate in]
34
+ top_news_template = %i[lang country max image]
35
+ template = search_template + top_news_template
36
+ (args.keys - template).empty?
37
+ end
38
+
39
+ def country_valid?(args)
40
+ args[:country].nil? ? true : COUNTRIES.include?(args[:country].downcase)
41
+ end
42
+
43
+ def date_valid?(args)
44
+ if args[:mindate].nil? && args[:maxdate].nil?
45
+ true
46
+ elsif args[:mindate] && args[:maxdate]
47
+ (args[:mindate].respond_to?(:strftime) && args[:maxdate].respond_to?(:strftime))
48
+ elsif args[:mindate] && args[:maxdate].nil?
49
+ args[:mindate].respond_to?(:strftime)
50
+ elsif args[:mindate].nil? && args[:maxdate]
51
+ args[:maxdate].respond_to?(:strftime)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Validate
4
+ class NewsApiQueryValidator < BaseValidator
5
+ COUNTRIES = %w[ar au at be br bg ca cn co cu cz eg fr de gr hk hu in id ie il it jp lv lt my mx ma nl nz ng no ph pl pt ro ru sa rs sg sk si za kr se ch tw th tr ae ua gb us ve].freeze
6
+ CATEGORIES = %w[business entertainment general health science sports technology].freeze
7
+
8
+ def initialize(api_key, args:, format:, endpoint: nil)
9
+ raise 'API Key is required' unless key_present?(api_key)
10
+ raise 'Invalid parameter sequence' unless query_valid?(args, endpoint)
11
+ raise 'Invalid country sent' unless country_valid?(args)
12
+ raise 'Invalid language sent' unless language_valid?(args)
13
+ raise 'Invalid date or dates sent' unless date_valid?(args)
14
+
15
+ true
16
+ end
17
+
18
+ private
19
+
20
+ def query_valid?(args, endpoint = 'top-headlines')
21
+ case endpoint
22
+ when 'top-headlines'
23
+ template = %i[q country category sources page_size page]
24
+ when 'everything'
25
+ template = %i[q sources domains excludeDomains
26
+ from to language sortBy pageSize page]
27
+ when 'sources'
28
+ template = %i[category language country]
29
+ end
30
+
31
+ if endpoint == 'top-headlines' && (args.include?(:sources) && (args.include?(:country) || args.include?(:category)))
32
+ false
33
+ elsif (endpoint == 'sources') && args.key?(:category) && (CATEGORIES.include?(args[:category]) == false)
34
+ false
35
+ else
36
+ (args.keys - template).empty?
37
+ end
38
+ end
39
+
40
+ def country_valid?(args)
41
+ args[:country].nil? ? true : COUNTRIES.include?(args[:country].downcase)
42
+ end
43
+
44
+ def category_valid?(args)
45
+ template = %w[business entertainment general health science sports technology]
46
+ template.include?(args[:country])
47
+ end
48
+
49
+ def date_valid?(args)
50
+ if args[:from].nil? && args[:to].nil?
51
+ true
52
+ elsif args[:from] && args[:to]
53
+ (args[:from].respond_to?(:strftime) && args['to'].respond_to?(:strftime))
54
+ elsif args[:from] && args['to'].nil?
55
+ args[:from].respond_to?(:strftime)
56
+ elsif args[:from].nil? && args['to']
57
+ args[:from].respond_to?(:strftime)
58
+ end
59
+ end
60
+ end
61
+ end