searchapi 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 (51) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +175 -0
  3. data/bin/test +14 -0
  4. data/lib/searchapi/error_result.rb +50 -0
  5. data/lib/searchapi/google_finance_options.rb +40 -0
  6. data/lib/searchapi/google_finance_request.rb +26 -0
  7. data/lib/searchapi/google_finance_result.rb +262 -0
  8. data/lib/searchapi/google_flights_options.rb +85 -0
  9. data/lib/searchapi/google_flights_request.rb +25 -0
  10. data/lib/searchapi/google_flights_result.rb +275 -0
  11. data/lib/searchapi/google_images_options.rb +64 -0
  12. data/lib/searchapi/google_images_request.rb +26 -0
  13. data/lib/searchapi/google_images_result.rb +133 -0
  14. data/lib/searchapi/google_light_options.rb +43 -0
  15. data/lib/searchapi/google_light_request.rb +26 -0
  16. data/lib/searchapi/google_light_result.rb +198 -0
  17. data/lib/searchapi/google_local_options.rb +40 -0
  18. data/lib/searchapi/google_local_request.rb +26 -0
  19. data/lib/searchapi/google_local_result.rb +85 -0
  20. data/lib/searchapi/google_news_light_options.rb +47 -0
  21. data/lib/searchapi/google_news_light_request.rb +26 -0
  22. data/lib/searchapi/google_news_light_result.rb +94 -0
  23. data/lib/searchapi/google_news_options.rb +53 -0
  24. data/lib/searchapi/google_news_portal_options.rb +40 -0
  25. data/lib/searchapi/google_news_portal_request.rb +89 -0
  26. data/lib/searchapi/google_news_portal_result.rb +137 -0
  27. data/lib/searchapi/google_news_request.rb +26 -0
  28. data/lib/searchapi/google_news_result.rb +129 -0
  29. data/lib/searchapi/google_scholar_options.rb +48 -0
  30. data/lib/searchapi/google_scholar_request.rb +26 -0
  31. data/lib/searchapi/google_scholar_result.rb +195 -0
  32. data/lib/searchapi/google_search_options.rb +67 -0
  33. data/lib/searchapi/google_search_request.rb +26 -0
  34. data/lib/searchapi/google_search_result.rb +301 -0
  35. data/lib/searchapi/helpers.rb +10 -0
  36. data/lib/searchapi/instagram_profile_options.rb +31 -0
  37. data/lib/searchapi/instagram_profile_request.rb +26 -0
  38. data/lib/searchapi/instagram_profile_result.rb +117 -0
  39. data/lib/searchapi/module_methods.rb +80 -0
  40. data/lib/searchapi/request.rb +25 -0
  41. data/lib/searchapi/response_methods.rb +14 -0
  42. data/lib/searchapi/tiktok_profile_options.rb +31 -0
  43. data/lib/searchapi/tiktok_profile_request.rb +26 -0
  44. data/lib/searchapi/tiktok_profile_result.rb +71 -0
  45. data/lib/searchapi/version.rb +3 -0
  46. data/lib/searchapi/youtube_search_options.rb +62 -0
  47. data/lib/searchapi/youtube_search_request.rb +26 -0
  48. data/lib/searchapi/youtube_search_result.rb +411 -0
  49. data/lib/searchapi.rb +70 -0
  50. data/searchapi.gemspec +37 -0
  51. metadata +164 -0
@@ -0,0 +1,89 @@
1
+ module SearchAPI
2
+ class GoogleNewsPortalRequest < Request
3
+
4
+ def search( query = nil, options = nil, &block )
5
+ if options
6
+ options = options.is_a?( GoogleNewsPortalOptions ) ? options : GoogleNewsPortalOptions.build!( options.to_h )
7
+ options = options.to_h
8
+ else
9
+ options = { engine: 'google_news_portal' }
10
+ end
11
+ options[ :q ] = query.to_s if query
12
+
13
+ response = get( "#{ BASE_URI }/search", options, &block )
14
+ attributes = ( JSON.parse( response.body, symbolize_names: true ) rescue nil )
15
+
16
+ result = if response.success?
17
+ GoogleNewsPortalResult.new( attributes || {} )
18
+ else
19
+ ErrorResult.new( response.status, attributes )
20
+ end
21
+
22
+ ResponseMethods.install( response, result )
23
+ end
24
+
25
+ def story( story_token, options = nil, &block )
26
+ if options
27
+ options = options.is_a?( GoogleNewsPortalOptions ) ? options : GoogleNewsPortalOptions.build!( options.to_h )
28
+ options = options.to_h
29
+ else
30
+ options = { engine: 'google_news_portal' }
31
+ end
32
+ options[ :story_token ] = story_token.to_s
33
+
34
+ response = get( "#{ BASE_URI }/search", options, &block )
35
+ attributes = ( JSON.parse( response.body, symbolize_names: true ) rescue nil )
36
+
37
+ result = if response.success?
38
+ GoogleNewsPortalResult.new( attributes || {} )
39
+ else
40
+ ErrorResult.new( response.status, attributes )
41
+ end
42
+
43
+ ResponseMethods.install( response, result )
44
+ end
45
+
46
+ def topic( topic_token, options = nil, &block )
47
+ if options
48
+ options = options.is_a?( GoogleNewsPortalOptions ) ? options : GoogleNewsPortalOptions.build!( options.to_h )
49
+ options = options.to_h
50
+ else
51
+ options = { engine: 'google_news_portal' }
52
+ end
53
+ options[ :topic_token ] = topic_token.to_s
54
+
55
+ response = get( "#{ BASE_URI }/search", options, &block )
56
+ attributes = ( JSON.parse( response.body, symbolize_names: true ) rescue nil )
57
+
58
+ result = if response.success?
59
+ GoogleNewsPortalResult.new( attributes || {} )
60
+ else
61
+ ErrorResult.new( response.status, attributes )
62
+ end
63
+
64
+ ResponseMethods.install( response, result )
65
+ end
66
+
67
+ def publication( publication_token, options = nil, &block )
68
+ if options
69
+ options = options.is_a?( GoogleNewsPortalOptions ) ? options : GoogleNewsPortalOptions.build!( options.to_h )
70
+ options = options.to_h
71
+ else
72
+ options = { engine: 'google_news_portal' }
73
+ end
74
+ options[ :publication_token ] = publication_token.to_s
75
+
76
+ response = get( "#{ BASE_URI }/search", options, &block )
77
+ attributes = ( JSON.parse( response.body, symbolize_names: true ) rescue nil )
78
+
79
+ result = if response.success?
80
+ GoogleNewsPortalResult.new( attributes || {} )
81
+ else
82
+ ErrorResult.new( response.status, attributes )
83
+ end
84
+
85
+ ResponseMethods.install( response, result )
86
+ end
87
+
88
+ end
89
+ end
@@ -0,0 +1,137 @@
1
+ require 'forwardable'
2
+
3
+ module SearchAPI
4
+
5
+ GoogleNewsPortalMetadataSchema = DynamicSchema::Struct.define do
6
+ id String
7
+ status String
8
+ created_at String, as: :created_at
9
+ request_time_taken Float, as: :request_time_taken
10
+ parsing_time_taken Float, as: :parsing_time_taken
11
+ total_time_taken Float, as: :total_time_taken
12
+ request_url String, as: :request_url
13
+ html_url String, as: :html_url
14
+ json_url String, as: :json_url
15
+ end
16
+
17
+ class GoogleNewsPortalMetadata < GoogleNewsPortalMetadataSchema
18
+ end
19
+
20
+ GoogleNewsPortalParametersSchema = DynamicSchema::Struct.define do
21
+ engine String
22
+ q String
23
+ ceid String
24
+ story_token String, as: :story_token
25
+ topic_token String, as: :topic_token
26
+ publication_token String, as: :publication_token
27
+ section_token String, as: :section_token
28
+ sort_by String, as: :sort_by
29
+ end
30
+
31
+ class GoogleNewsPortalParameters < GoogleNewsPortalParametersSchema
32
+ end
33
+
34
+ GoogleNewsPortalSourceSchema = DynamicSchema::Struct.define do
35
+ name String
36
+ favicon String
37
+ authors String, array: true
38
+ end
39
+
40
+ class GoogleNewsPortalSource < GoogleNewsPortalSourceSchema
41
+ end
42
+
43
+ GoogleNewsPortalArticleSchema = DynamicSchema::Struct.define do
44
+ position Integer
45
+ title String
46
+ link String
47
+ thumbnail String
48
+ iso_date String, as: :iso_date
49
+ story_token String, as: :story_token
50
+ story_title String, as: :story_title
51
+ section String
52
+ source GoogleNewsPortalSource
53
+ end
54
+
55
+ class GoogleNewsPortalArticle < GoogleNewsPortalArticleSchema
56
+ end
57
+
58
+ GoogleNewsPortalMenuTopicSchema = DynamicSchema::Struct.define do
59
+ title String
60
+ topic_token String, as: :topic_token
61
+ end
62
+
63
+ class GoogleNewsPortalMenuTopic < GoogleNewsPortalMenuTopicSchema
64
+ end
65
+
66
+ GoogleNewsPortalRelatedTopicSchema = DynamicSchema::Struct.define do
67
+ title String
68
+ topic_token String, as: :topic_token
69
+ thumbnail String
70
+ end
71
+
72
+ class GoogleNewsPortalRelatedTopic < GoogleNewsPortalRelatedTopicSchema
73
+ end
74
+
75
+ GoogleNewsPortalRelatedPublicationSchema = DynamicSchema::Struct.define do
76
+ name String
77
+ publication_token String, as: :publication_token
78
+ thumbnail String
79
+ end
80
+
81
+ class GoogleNewsPortalRelatedPublication < GoogleNewsPortalRelatedPublicationSchema
82
+ end
83
+
84
+ GoogleNewsPortalSubMenuSectionSchema = DynamicSchema::Struct.define do
85
+ title String
86
+ section_token String, as: :section_token
87
+ end
88
+
89
+ class GoogleNewsPortalSubMenuSection < GoogleNewsPortalSubMenuSectionSchema
90
+ end
91
+
92
+ GoogleNewsPortalPostOnXSchema = DynamicSchema::Struct.define do
93
+ link String
94
+ snippet String
95
+ author String
96
+ author_link String, as: :author_link
97
+ author_thumbnail String, as: :author_thumbnail
98
+ date String
99
+ end
100
+
101
+ class GoogleNewsPortalPostOnX < GoogleNewsPortalPostOnXSchema
102
+ end
103
+
104
+ GoogleNewsPortalFAQSchema = DynamicSchema::Struct.define do
105
+ question String
106
+ answer String
107
+ link String
108
+ end
109
+
110
+ class GoogleNewsPortalFAQ < GoogleNewsPortalFAQSchema
111
+ end
112
+
113
+ GoogleNewsPortalResultSchema = DynamicSchema::Struct.define do
114
+ search_metadata GoogleNewsPortalMetadata, as: :search_metadata
115
+ search_parameters GoogleNewsPortalParameters, as: :search_parameters
116
+ organic_results GoogleNewsPortalArticle, array: true, as: :organic_results
117
+ menu_topics GoogleNewsPortalMenuTopic, array: true, as: :menu_topics
118
+ related_topics GoogleNewsPortalRelatedTopic, array: true, as: :related_topics
119
+ related_publications GoogleNewsPortalRelatedPublication, array: true, as: :related_publications
120
+ sub_menu_sections GoogleNewsPortalSubMenuSection, array: true, as: :sub_menu_sections
121
+ posts_on_x GoogleNewsPortalPostOnX, array: true, as: :posts_on_x
122
+ frequently_asked_questions GoogleNewsPortalFAQ, array: true, as: :frequently_asked_questions
123
+ error String
124
+ end
125
+
126
+ class GoogleNewsPortalResult < GoogleNewsPortalResultSchema
127
+ extend Forwardable
128
+ include Enumerable
129
+
130
+ def_delegators :organic_results, :each, :[], :count, :size, :length, :first, :last, :empty?
131
+
132
+ def success?
133
+ self.error.nil?
134
+ end
135
+ end
136
+
137
+ end
@@ -0,0 +1,26 @@
1
+ module SearchAPI
2
+ class GoogleNewsRequest < Request
3
+
4
+ def search( query, options = nil, &block )
5
+ if options
6
+ options = options.is_a?( GoogleNewsOptions ) ? options : GoogleNewsOptions.build!( options.to_h )
7
+ options = options.to_h
8
+ else
9
+ options = { engine: 'google_news' }
10
+ end
11
+ options[ :q ] = query.to_s
12
+
13
+ response = get( "#{ BASE_URI }/search", options, &block )
14
+ attributes = ( JSON.parse( response.body, symbolize_names: true ) rescue nil )
15
+
16
+ result = if response.success?
17
+ GoogleNewsResult.new( attributes || {} )
18
+ else
19
+ ErrorResult.new( response.status, attributes )
20
+ end
21
+
22
+ ResponseMethods.install( response, result )
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,129 @@
1
+ require 'forwardable'
2
+
3
+ module SearchAPI
4
+
5
+ GoogleNewsMetadataSchema = DynamicSchema::Struct.define do
6
+ id String
7
+ status String
8
+ created_at String, as: :created_at
9
+ request_time_taken Float, as: :request_time_taken
10
+ parsing_time_taken Float, as: :parsing_time_taken
11
+ total_time_taken Float, as: :total_time_taken
12
+ request_url String, as: :request_url
13
+ html_url String, as: :html_url
14
+ json_url String, as: :json_url
15
+ end
16
+
17
+ class GoogleNewsMetadata < GoogleNewsMetadataSchema
18
+ end
19
+
20
+ GoogleNewsParametersSchema = DynamicSchema::Struct.define do
21
+ engine String
22
+ q String
23
+ device String
24
+ uule String
25
+ location String
26
+ location_used String, as: :location_used
27
+ google_domain String, as: :google_domain
28
+ hl String
29
+ gl String
30
+ lr String
31
+ cr String
32
+ nfpr String
33
+ filter String
34
+ safe String
35
+ page String
36
+ time_period String, as: :time_period
37
+ time_period_min String, as: :time_period_min
38
+ time_period_max String, as: :time_period_max
39
+ sort_by String, as: :sort_by
40
+ end
41
+
42
+ class GoogleNewsParameters < GoogleNewsParametersSchema
43
+ end
44
+
45
+ GoogleNewsSearchInformationSchema = DynamicSchema::Struct.define do
46
+ query_displayed String, as: :query_displayed
47
+ total_results Integer, as: :total_results
48
+ page Integer
49
+ time_taken_displayed Float, as: :time_taken_displayed
50
+ detected_location String, as: :detected_location
51
+ did_you_mean String, as: :did_you_mean
52
+ has_no_results_for [ TrueClass, FalseClass ], as: :has_no_results_for
53
+ showing_results_for String, as: :showing_results_for
54
+ end
55
+
56
+ class GoogleNewsSearchInformation < GoogleNewsSearchInformationSchema
57
+ end
58
+
59
+ GoogleNewsArticleSchema = DynamicSchema::Struct.define do
60
+ position Integer
61
+ title String
62
+ link String
63
+ source String
64
+ date String
65
+ snippet String
66
+ is_live [ TrueClass, FalseClass ], as: :is_live
67
+ favicon String
68
+ thumbnail String
69
+ end
70
+
71
+ class GoogleNewsArticle < GoogleNewsArticleSchema
72
+ end
73
+
74
+ GoogleNewsTopStorySchema = DynamicSchema::Struct.define do
75
+ title String
76
+ link String
77
+ author String
78
+ author_link String, as: :author_link
79
+ source String
80
+ date String
81
+ snippet String
82
+ is_live [ TrueClass, FalseClass ], as: :is_live
83
+ is_video [ TrueClass, FalseClass ], as: :is_video
84
+ thumbnail String
85
+ end
86
+
87
+ class GoogleNewsTopStory < GoogleNewsTopStorySchema
88
+ end
89
+
90
+ GoogleNewsMoreLinkSchema = DynamicSchema::Struct.define do
91
+ link String
92
+ end
93
+
94
+ class GoogleNewsMoreLink < GoogleNewsMoreLinkSchema
95
+ end
96
+
97
+ GoogleNewsPaginationSchema = DynamicSchema::Struct.define do
98
+ current Integer
99
+ previous String
100
+ _value :next, type: String
101
+ other_pages Hash, as: :other_pages
102
+ end
103
+
104
+ class GoogleNewsPagination < GoogleNewsPaginationSchema
105
+ end
106
+
107
+ GoogleNewsResultSchema = DynamicSchema::Struct.define do
108
+ search_metadata GoogleNewsMetadata, as: :search_metadata
109
+ search_parameters GoogleNewsParameters, as: :search_parameters
110
+ search_information GoogleNewsSearchInformation, as: :search_information
111
+ organic_results GoogleNewsArticle, array: true, as: :organic_results
112
+ top_stories GoogleNewsTopStory, array: true, as: :top_stories
113
+ top_stories_more_link GoogleNewsMoreLink, as: :top_stories_more_link
114
+ pagination GoogleNewsPagination
115
+ error String
116
+ end
117
+
118
+ class GoogleNewsResult < GoogleNewsResultSchema
119
+ extend Forwardable
120
+ include Enumerable
121
+
122
+ def_delegators :organic_results, :each, :[], :count, :size, :length, :first, :last, :empty?
123
+
124
+ def success?
125
+ self.error.nil?
126
+ end
127
+ end
128
+
129
+ end
@@ -0,0 +1,48 @@
1
+ module SearchAPI
2
+ class GoogleScholarOptions
3
+ include DynamicSchema::Definable
4
+ include Helpers
5
+
6
+ SAFE_SEARCH = %w[ active off ]
7
+ NORMALIZE_DOWNCASE = ->(v) { v.to_s.downcase }
8
+
9
+ schema do
10
+ q String
11
+ cites String
12
+ cluster String
13
+ hl String
14
+ lr String
15
+ safe String, in: SAFE_SEARCH, normalize: NORMALIZE_DOWNCASE
16
+ filter Integer
17
+ as_ylo Integer
18
+ as_yhi Integer
19
+ scisbd Integer
20
+ as_vis Integer
21
+ as_rr Integer
22
+ as_sdt String
23
+ source String
24
+ num Integer, in: 1..20
25
+ page Integer
26
+ end
27
+
28
+ def self.build( options = nil, &block )
29
+ new( api_options: builder.build( options, &block ) )
30
+ end
31
+
32
+ def self.build!( options = nil, &block )
33
+ new( api_options: builder.build!( options, &block ) )
34
+ end
35
+
36
+ def initialize( options = {}, api_options: nil )
37
+ @options = self.class.builder.build( options || {} )
38
+ @options = api_options.merge( @options ) if api_options
39
+ end
40
+
41
+ def to_h
42
+ result = @options.to_h
43
+ result[ :engine ] = 'google_scholar'
44
+ result
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,26 @@
1
+ module SearchAPI
2
+ class GoogleScholarRequest < Request
3
+
4
+ def search( query = nil, options = nil, &block )
5
+ if options
6
+ options = options.is_a?( GoogleScholarOptions ) ? options : GoogleScholarOptions.build!( options.to_h )
7
+ options = options.to_h
8
+ else
9
+ options = { engine: 'google_scholar' }
10
+ end
11
+ options[ :q ] = query.to_s if query
12
+
13
+ response = get( "#{ BASE_URI }/search", options, &block )
14
+ attributes = ( JSON.parse( response.body, symbolize_names: true ) rescue nil )
15
+
16
+ result = if response.success?
17
+ GoogleScholarResult.new( attributes || {} )
18
+ else
19
+ ErrorResult.new( response.status, attributes )
20
+ end
21
+
22
+ ResponseMethods.install( response, result )
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,195 @@
1
+ require 'forwardable'
2
+
3
+ module SearchAPI
4
+
5
+ GoogleScholarMetadataSchema = DynamicSchema::Struct.define do
6
+ id String
7
+ status String
8
+ created_at String, as: :created_at
9
+ request_time_taken Float, as: :request_time_taken
10
+ parsing_time_taken Float, as: :parsing_time_taken
11
+ total_time_taken Float, as: :total_time_taken
12
+ request_url String, as: :request_url
13
+ html_url String, as: :html_url
14
+ json_url String, as: :json_url
15
+ end
16
+
17
+ class GoogleScholarMetadata < GoogleScholarMetadataSchema
18
+ end
19
+
20
+ GoogleScholarParametersSchema = DynamicSchema::Struct.define do
21
+ engine String
22
+ q String
23
+ cites String
24
+ cluster String
25
+ hl String
26
+ lr String
27
+ scisbd Integer
28
+ as_ylo Integer, as: :as_ylo
29
+ as_yhi Integer, as: :as_yhi
30
+ as_rr Integer, as: :as_rr
31
+ as_vis Integer, as: :as_vis
32
+ as_sdt String, as: :as_sdt
33
+ filter Integer
34
+ safe String
35
+ source String
36
+ num Integer
37
+ page Integer
38
+ end
39
+
40
+ class GoogleScholarParameters < GoogleScholarParametersSchema
41
+ end
42
+
43
+ GoogleScholarDidYouMeanSchema = DynamicSchema::Struct.define do
44
+ text String
45
+ link String
46
+ end
47
+
48
+ class GoogleScholarDidYouMean < GoogleScholarDidYouMeanSchema
49
+ end
50
+
51
+ GoogleScholarSearchInformationSchema = DynamicSchema::Struct.define do
52
+ total_results Integer, as: :total_results
53
+ page Integer
54
+ time_taken_displayed Float, as: :time_taken_displayed
55
+ query_displayed String, as: :query_displayed
56
+ did_you_mean GoogleScholarDidYouMean, as: :did_you_mean
57
+ end
58
+
59
+ class GoogleScholarSearchInformation < GoogleScholarSearchInformationSchema
60
+ end
61
+
62
+ GoogleScholarCitedBySchema = DynamicSchema::Struct.define do
63
+ total Integer
64
+ end
65
+
66
+ class GoogleScholarCitedBy < GoogleScholarCitedBySchema
67
+ end
68
+
69
+ GoogleScholarProfileSchema = DynamicSchema::Struct.define do
70
+ name String
71
+ link String
72
+ author_id String, as: :author_id
73
+ affiliations String
74
+ email String
75
+ cited_by GoogleScholarCitedBy, as: :cited_by
76
+ end
77
+
78
+ class GoogleScholarProfile < GoogleScholarProfileSchema
79
+ end
80
+
81
+ GoogleScholarOrganizationSchema = DynamicSchema::Struct.define do
82
+ name String
83
+ link String
84
+ org_id String, as: :org_id
85
+ university String
86
+ end
87
+
88
+ class GoogleScholarOrganization < GoogleScholarOrganizationSchema
89
+ end
90
+
91
+ GoogleScholarResourceSchema = DynamicSchema::Struct.define do
92
+ name String
93
+ format String
94
+ link String
95
+ end
96
+
97
+ class GoogleScholarResource < GoogleScholarResourceSchema
98
+ end
99
+
100
+ GoogleScholarAuthorSchema = DynamicSchema::Struct.define do
101
+ name String
102
+ id String
103
+ link String
104
+ end
105
+
106
+ class GoogleScholarAuthor < GoogleScholarAuthorSchema
107
+ end
108
+
109
+ GoogleScholarCitedByLinkSchema = DynamicSchema::Struct.define do
110
+ total Integer
111
+ link String
112
+ cites_id String, as: :cites_id
113
+ end
114
+
115
+ class GoogleScholarCitedByLink < GoogleScholarCitedByLinkSchema
116
+ end
117
+
118
+ GoogleScholarVersionsSchema = DynamicSchema::Struct.define do
119
+ total Integer
120
+ link String
121
+ cluster_id String, as: :cluster_id
122
+ end
123
+
124
+ class GoogleScholarVersions < GoogleScholarVersionsSchema
125
+ end
126
+
127
+ GoogleScholarInlineLinksSchema = DynamicSchema::Struct.define do
128
+ cited_by GoogleScholarCitedByLink, as: :cited_by
129
+ versions GoogleScholarVersions
130
+ related_articles_link String, as: :related_articles_link
131
+ cached_page_link String, as: :cached_page_link
132
+ end
133
+
134
+ class GoogleScholarInlineLinks < GoogleScholarInlineLinksSchema
135
+ end
136
+
137
+ GoogleScholarArticleSchema = DynamicSchema::Struct.define do
138
+ position Integer
139
+ title String
140
+ link String
141
+ data_cid String, as: :data_cid
142
+ type String
143
+ publication String
144
+ snippet String
145
+ resource GoogleScholarResource
146
+ authors GoogleScholarAuthor, array: true
147
+ inline_links GoogleScholarInlineLinks, as: :inline_links
148
+ end
149
+
150
+ class GoogleScholarArticle < GoogleScholarArticleSchema
151
+ end
152
+
153
+ GoogleScholarRelatedSearchSchema = DynamicSchema::Struct.define do
154
+ query String
155
+ highlighted String, array: true
156
+ link String
157
+ end
158
+
159
+ class GoogleScholarRelatedSearch < GoogleScholarRelatedSearchSchema
160
+ end
161
+
162
+ GoogleScholarPaginationSchema = DynamicSchema::Struct.define do
163
+ current Integer
164
+ previous String
165
+ _value :next, type: String
166
+ other_pages Hash, as: :other_pages
167
+ end
168
+
169
+ class GoogleScholarPagination < GoogleScholarPaginationSchema
170
+ end
171
+
172
+ GoogleScholarResultSchema = DynamicSchema::Struct.define do
173
+ search_metadata GoogleScholarMetadata, as: :search_metadata
174
+ search_parameters GoogleScholarParameters, as: :search_parameters
175
+ search_information GoogleScholarSearchInformation, as: :search_information
176
+ profiles GoogleScholarProfile, array: true
177
+ organizations GoogleScholarOrganization, array: true
178
+ organic_results GoogleScholarArticle, array: true, as: :organic_results
179
+ related_searches GoogleScholarRelatedSearch, array: true, as: :related_searches
180
+ pagination GoogleScholarPagination
181
+ error String
182
+ end
183
+
184
+ class GoogleScholarResult < GoogleScholarResultSchema
185
+ extend Forwardable
186
+ include Enumerable
187
+
188
+ def_delegators :organic_results, :each, :[], :count, :size, :length, :first, :last, :empty?
189
+
190
+ def success?
191
+ self.error.nil?
192
+ end
193
+ end
194
+
195
+ end