metonym 1.0.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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