openfoodfacts 0.5.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b0d0dfc51ebc907f81991a5725a81139000c7487
4
- data.tar.gz: 32d96c22c65f92a5de7b2d082dce6c70a3be68d9
2
+ SHA256:
3
+ metadata.gz: 8ee85e6766c13c0afa60c4800d43c99c85282f3544427d725cee0a97023631d9
4
+ data.tar.gz: 054c0a1972297b84f91b7c3d3d96006655d29f755f781800ec80808b297e840f
5
5
  SHA512:
6
- metadata.gz: d6e3f8bef342ec68d4e95067374f5d428221f0f0f3c0d2ecaef9c96a221461c8a07000ae708446b5f72c61df93aaeb7333102c54f1c353cb823f0141c792de58
7
- data.tar.gz: 02a3b387e5492379f6c687449a0bef6cd6ace94161330d36dc4a90d48a2eddce233fce9ae65ac0ffbfc472b20813d08233f03da11936f255b6876598fa6b64b4
6
+ metadata.gz: 7e9a7773561119e9b32f16677848dd28b54ce4c31f740d5a1f7b3f9592c6798d739d2815030bd507a4ed8df318f30f3fcaf06f26700f36dd26b67f45e2280099
7
+ data.tar.gz: d188187e2245d87ef1bd051485212f24bce554d7f9add603559617bea6353831535f21dcac65cc008b21492cf50ebdf0b3006359fcf531f7b0bd0ea3d51df5c5
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/openfoodfacts.svg)](https://badge.fury.io/rb/openfoodfacts)
4
4
  [![Build Status](https://travis-ci.org/openfoodfacts/openfoodfacts-ruby.svg?branch=master)](https://travis-ci.org/openfoodfacts/openfoodfacts-ruby)
5
+ [![Build status](https://ci.appveyor.com/api/projects/status/tarhvc59fw478das/branch/master?svg=true)](https://ci.appveyor.com/project/nicolasleger/openfoodfacts-ruby/branch/master)
5
6
  [![Dependency Status](https://gemnasium.com/openfoodfacts/openfoodfacts-ruby.svg)](https://gemnasium.com/openfoodfacts/openfoodfacts-ruby)
6
7
  [![Code Climate](https://codeclimate.com/github/openfoodfacts/openfoodfacts-ruby/badges/gpa.svg)](https://codeclimate.com/github/openfoodfacts/openfoodfacts-ruby)
7
8
  [![Coverage Status](https://coveralls.io/repos/github/openfoodfacts/openfoodfacts-ruby/badge.svg?branch=master)](https://coveralls.io/github/openfoodfacts/openfoodfacts-ruby?branch=master)
@@ -16,7 +16,7 @@ module Openfoodfacts
16
16
  class << self
17
17
  def items(locale: DEFAULT_LOCALE, domain: DEFAULT_DOMAIN)
18
18
  if path = LOCALE_PATHS[locale]
19
- html = open("https://#{locale}.#{domain}/#{path}").read
19
+ html = URI.open("https://#{locale}.#{domain}/#{path}").read
20
20
  dom = Nokogiri::HTML.fragment(html)
21
21
 
22
22
  titles = dom.css('#main_column h2')
@@ -1,3 +1,5 @@
1
+ require 'open-uri'
2
+
1
3
  module Openfoodfacts
2
4
  class Locale < String
3
5
 
@@ -8,12 +10,13 @@ module Openfoodfacts
8
10
  # Get locales
9
11
  #
10
12
  def all(domain: DEFAULT_DOMAIN)
11
- url = "https://#{domain}/"
12
- body = open(url).read
13
- dom = Nokogiri.parse(body)
13
+ path = 'cgi/i18n/countries.pl?_type=query'
14
+ url = "https://#{GLOBAL}.#{domain}/#{path}"
15
+ json = URI.open(url).read
16
+ hash = JSON.parse(json)
14
17
 
15
- dom.css('#select_country option').map { |option|
16
- locale_from_option(option, domain: domain)
18
+ hash.map { |pair|
19
+ locale_from_pair(pair, domain: domain)
17
20
  }.compact
18
21
  end
19
22
 
@@ -24,15 +27,15 @@ module Openfoodfacts
24
27
  locale unless locale.nil? || locale == 'static'
25
28
  end
26
29
 
27
- # Return locale from option
30
+ # Return locale from pair
28
31
  #
29
- def locale_from_option(option, domain: DEFAULT_DOMAIN)
30
- value = option.attr('value')
32
+ def locale_from_pair(pair, domain: DEFAULT_DOMAIN)
33
+ code = pair.first
31
34
  {
32
- "name" => option.text.strip,
33
- "code" => value,
34
- "url" => "https://#{value}.#{domain}"
35
- } if value
35
+ "name" => pair.last.strip,
36
+ "code" => code,
37
+ "url" => "https://#{code}.#{domain}"
38
+ } if code
36
39
  end
37
40
 
38
41
  end
@@ -1,4 +1,5 @@
1
1
  require 'hashie'
2
+ require 'open-uri'
2
3
 
3
4
  module Openfoodfacts
4
5
  class Mission < Hashie::Mash
@@ -15,7 +16,7 @@ module Openfoodfacts
15
16
  def all(locale: DEFAULT_LOCALE, domain: DEFAULT_DOMAIN)
16
17
  if path = LOCALE_PATHS[locale]
17
18
  url = "https://#{locale}.#{domain}/#{path}"
18
- html = open(url).read
19
+ html = URI.open(url).read
19
20
  dom = Nokogiri::HTML.fragment(html)
20
21
 
21
22
  dom.css('#missions li').map do |mission_dom|
@@ -38,7 +39,7 @@ module Openfoodfacts
38
39
  #
39
40
  def fetch
40
41
  if (self.url)
41
- html = open(self.url).read
42
+ html = URI.open(self.url).read
42
43
  dom = Nokogiri::HTML.fragment(html)
43
44
 
44
45
  description = dom.css('#description').first
@@ -8,44 +8,34 @@ module Openfoodfacts
8
8
 
9
9
  # TODO: Add more locales
10
10
  LOCALE_PATHS = {
11
- 'fr' => 'presse',
12
- 'uk' => 'press',
13
- 'us' => 'press',
14
- 'world' => 'press'
11
+ 'fr' => 'revue-de-presse-fr'
15
12
  }
16
13
 
17
14
  LOCALE_DATE_FORMATS = {
18
- 'fr' => '%d/%m/%Y',
19
- 'uk' => '%d/%m/%Y',
20
- 'us' => '%d/%m/%Y',
21
- 'world' => '%d/%m/%Y'
15
+ 'fr' => '%d/%m/%Y'
22
16
  }
23
17
 
24
18
  class << self
25
- def items(locale: DEFAULT_LOCALE, domain: DEFAULT_DOMAIN)
19
+ def items(locale: 'fr', domain: DEFAULT_DOMAIN)
26
20
  if path = LOCALE_PATHS[locale]
27
- html = open("https://#{locale}.#{domain}/#{path}").read
21
+ date_format = LOCALE_DATE_FORMATS[locale]
22
+
23
+ html = URI.open("https://#{locale}.#{domain}/#{path}").read
28
24
  dom = Nokogiri::HTML.fragment(html)
29
25
 
30
- titles = dom.css('#main_column li')
26
+ titles = dom.css('#press_table tbody tr')
31
27
  titles.each_with_index.map do |item, index|
32
- data = item.inner_html.split(' - ')
28
+ colums = item.css('td')
33
29
 
34
- link = Nokogiri::HTML.fragment(data.first).css('a')
30
+ link = colums[1].css('a')
35
31
  attributes = {
36
- "title" => link.text.strip,
37
- "url" => link.attr('href').value
32
+ "type" => colums[0].text,
33
+ "title" => colums[1].text.strip,
34
+ "url" => link && link.attr('href') && link.attr('href').value,
35
+ "source" => colums[2].text.strip,
36
+ "date" => (DateTime.strptime(colums[3].text, date_format) rescue nil)
38
37
  }
39
38
 
40
- last = Nokogiri::HTML.fragment(data.last)
41
- if date_format = LOCALE_DATE_FORMATS[locale] and date = last.text.strip[/\d+\/\d+\/\d+\z/, 0]
42
- attributes["date"] = DateTime.strptime(date, date_format)
43
- end
44
-
45
- if data.length >= 3
46
- attributes["source"] = Nokogiri::HTML.fragment(data[-2]).text.strip
47
- end
48
-
49
39
  new(attributes)
50
40
  end
51
41
  end
@@ -1,3 +1,4 @@
1
+ require 'cgi'
1
2
  require 'hashie'
2
3
  require 'net/http'
3
4
  require 'nokogiri'
@@ -21,7 +22,7 @@ module Openfoodfacts
21
22
  def get(code, locale: DEFAULT_LOCALE)
22
23
  if code
23
24
  product_url = url(code, locale: locale)
24
- json = open(product_url).read
25
+ json = URI.open(product_url).read
25
26
  hash = JSON.parse(json)
26
27
 
27
28
  new(hash["product"]) if !hash["status"].nil? && hash["status"] == 1
@@ -44,7 +45,7 @@ module Openfoodfacts
44
45
  terms = CGI.escape(terms)
45
46
  path = "cgi/search.pl?search_terms=#{terms}&jqm=1&page=#{page}&page_size=#{page_size}&sort_by=#{sort_by}"
46
47
  url = "https://#{locale}.#{domain}/#{path}"
47
- json = open(url).read
48
+ json = URI.open(url).read
48
49
  hash = JSON.parse(json)
49
50
  html = hash["jqm"]
50
51
 
@@ -78,7 +79,7 @@ module Openfoodfacts
78
79
  end
79
80
 
80
81
  def from_jquery_mobile_list(jqm_html)
81
- from_html_list(jqm_html, 'ul li:not(#loadmore)', /code=(\d+)\Z/i)
82
+ from_html_list(jqm_html, 'ul#search_results_list li:not(#loadmore)', /code=(\d+)\Z/i)
82
83
  end
83
84
 
84
85
  def from_website_list(html, locale: 'world')
@@ -104,13 +105,13 @@ module Openfoodfacts
104
105
  products
105
106
  end
106
107
  else
107
- html = open("#{page_url}/#{page}").read
108
+ html = URI.open("#{page_url}/#{page}").read
108
109
  from_website_list(html, locale: Locale.locale_from_link(page_url))
109
110
  end
110
111
  end
111
112
 
112
113
  def tags_from_page(_klass, page_url, &custom_tag_parsing)
113
- html = open(page_url).read
114
+ html = URI.open(page_url).read
114
115
  dom = Nokogiri::HTML.fragment(html)
115
116
 
116
117
  dom.css('table#tagstable tbody tr').map do |tag|
@@ -1,3 +1,3 @@
1
1
  module Openfoodfacts
2
- VERSION = "0.5.1"
2
+ VERSION = "0.6.0"
3
3
  end
@@ -6,7 +6,13 @@ require 'minitest/autorun'
6
6
  require 'webmock/minitest'
7
7
  require 'vcr'
8
8
 
9
+ # Avoid OpenSSL certificate verify failed error
10
+ if ENV.has_key?('APPVEYOR') && Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.4')
11
+ require 'openssl'
12
+ OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
13
+ end
14
+
9
15
  VCR.configure do |c|
10
16
  c.cassette_library_dir = "test/fixtures"
11
17
  c.hook_into :webmock
12
- end
18
+ end
@@ -103,8 +103,8 @@ class TestOpenfoodfacts < Minitest::Test
103
103
 
104
104
  def test_it_fetches_additives
105
105
  VCR.use_cassette("additives") do
106
- additives = ::Openfoodfacts::Additive.all(locale: 'fr') # FR to have riskiness
107
- assert_equal "https://fr.openfoodfacts.org/additif/e330-acide-citrique", additives.first.url
106
+ additives = ::Openfoodfacts::Additive.all # World to have riskiness
107
+ assert_includes additives.map { |additive| additive['url'] }, "https://world.openfoodfacts.org/additive/e330-citric-acid"
108
108
  refute_nil additives.detect { |additive| !additive['riskiness'].nil? }
109
109
  end
110
110
  end
@@ -112,7 +112,7 @@ class TestOpenfoodfacts < Minitest::Test
112
112
  def test_it_fetches_additives_for_locale
113
113
  VCR.use_cassette("additives_locale") do
114
114
  additives = ::Openfoodfacts::Additive.all(locale: 'fr')
115
- assert_equal "https://fr.openfoodfacts.org/additif/e330-acide-citrique", additives.first.url
115
+ assert_includes additives.map { |additive| additive['url'] }, "https://fr.openfoodfacts.org/additif/e330-acide-citrique"
116
116
  end
117
117
  end
118
118
 
@@ -201,14 +201,14 @@ class TestOpenfoodfacts < Minitest::Test
201
201
  def test_it_fetches_product_states
202
202
  VCR.use_cassette("product_states") do
203
203
  product_states = ::Openfoodfacts::ProductState.all
204
- assert_equal "https://world.openfoodfacts.org/state/empty", product_states.last.url
204
+ assert_equal "https://world.openfoodfacts.org/state/front-photo-not-selected", product_states.last.url
205
205
  end
206
206
  end
207
207
 
208
208
  def test_it_fetches_product_states_for_locale
209
209
  VCR.use_cassette("product_states_locale") do
210
210
  product_states = ::Openfoodfacts::ProductState.all(locale: 'fr')
211
- assert_equal "https://fr.openfoodfacts.org/etat/vide", product_states.last.url
211
+ assert_equal "https://fr.openfoodfacts.org/etat/en:front-photo-not-selected", product_states.last.url
212
212
  end
213
213
  end
214
214
 
@@ -261,7 +261,7 @@ class TestOpenfoodfacts < Minitest::Test
261
261
  end
262
262
 
263
263
  def test_it_fetches_products_for_last_edit_date
264
- last_edit_date = ::Openfoodfacts::LastEditDate.new("url" => "https://world.openfoodfacts.org/last-edit-date/2013-11-11")
264
+ last_edit_date = ::Openfoodfacts::LastEditDate.new("url" => "https://world.openfoodfacts.org/last-edit-date/2020-04")
265
265
  VCR.use_cassette("products_for_last_edit_date") do
266
266
  products_for_last_edit_date = last_edit_date.products(page: 1)
267
267
  refute_empty products_for_last_edit_date
@@ -304,12 +304,14 @@ class TestOpenfoodfacts < Minitest::Test
304
304
 
305
305
  def test_it_fetches_missions
306
306
  VCR.use_cassette("missions") do
307
+ skip("Website have a bug with Missions page on https://fr.openfoodfacts.org/missions")
307
308
  refute_empty ::Openfoodfacts::Mission.all(locale: 'fr')
308
309
  end
309
310
  end
310
311
 
311
312
  def test_it_fetches_mission
312
313
  VCR.use_cassette("mission", record: :once, match_requests_on: [:host, :path]) do
314
+ skip("Website have a bug with Mission page on https://fr.openfoodfacts.org/mission/informateur-100-produits")
313
315
  mission = ::Openfoodfacts::Mission.new(url: "https://fr.openfoodfacts.org/mission/informateur-100-produits")
314
316
  mission.fetch
315
317
  refute_empty mission.users
metadata CHANGED
@@ -1,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openfoodfacts
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nicolas Leger
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-10-30 00:00:00.000000000 Z
11
+ date: 2020-12-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: hashie
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '3.4'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.0'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: '3.4'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.0'
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: nokogiri
29
35
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +50,14 @@ dependencies:
44
50
  requirements:
45
51
  - - "~>"
46
52
  - !ruby/object:Gem::Version
47
- version: '1.8'
53
+ version: '2.1'
48
54
  type: :development
49
55
  prerelease: false
50
56
  version_requirements: !ruby/object:Gem::Requirement
51
57
  requirements:
52
58
  - - "~>"
53
59
  - !ruby/object:Gem::Version
54
- version: '1.8'
60
+ version: '2.1'
55
61
  - !ruby/object:Gem::Dependency
56
62
  name: rake
57
63
  requirement: !ruby/object:Gem::Requirement
@@ -86,31 +92,31 @@ dependencies:
86
92
  requirements:
87
93
  - - "~>"
88
94
  - !ruby/object:Gem::Version
89
- version: '3.0'
95
+ version: '5.1'
90
96
  type: :development
91
97
  prerelease: false
92
98
  version_requirements: !ruby/object:Gem::Requirement
93
99
  requirements:
94
100
  - - "~>"
95
101
  - !ruby/object:Gem::Version
96
- version: '3.0'
102
+ version: '5.1'
97
103
  - !ruby/object:Gem::Dependency
98
104
  name: webmock
99
105
  requirement: !ruby/object:Gem::Requirement
100
106
  requirements:
101
107
  - - "~>"
102
108
  - !ruby/object:Gem::Version
103
- version: '2.3'
109
+ version: '3.11'
104
110
  type: :development
105
111
  prerelease: false
106
112
  version_requirements: !ruby/object:Gem::Requirement
107
113
  requirements:
108
114
  - - "~>"
109
115
  - !ruby/object:Gem::Version
110
- version: '2.3'
116
+ version: '3.11'
111
117
  description: Open Food Facts API Wrapper, the open database about food.
112
118
  email:
113
- - nicolas.leger@nleger.com
119
+ - opensource@nleger.com
114
120
  executables: []
115
121
  extensions: []
116
122
  extra_rdoc_files: []
@@ -154,7 +160,7 @@ homepage: https://github.com/openfoodfacts/openfoodfacts-ruby
154
160
  licenses:
155
161
  - MIT
156
162
  metadata: {}
157
- post_install_message:
163
+ post_install_message:
158
164
  rdoc_options: []
159
165
  require_paths:
160
166
  - lib
@@ -162,16 +168,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
162
168
  requirements:
163
169
  - - ">="
164
170
  - !ruby/object:Gem::Version
165
- version: '2.0'
171
+ version: '2.5'
166
172
  required_rubygems_version: !ruby/object:Gem::Requirement
167
173
  requirements:
168
174
  - - ">="
169
175
  - !ruby/object:Gem::Version
170
176
  version: '0'
171
177
  requirements: []
172
- rubyforge_project:
173
- rubygems_version: 2.6.13
174
- signing_key:
178
+ rubygems_version: 3.2.3
179
+ signing_key:
175
180
  specification_version: 4
176
181
  summary: Open Food Facts API Wrapper
177
182
  test_files: []