openfoodfacts 0.5.1 → 0.6.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.
- checksums.yaml +5 -5
- data/README.md +1 -0
- data/lib/openfoodfacts/faq.rb +1 -1
- data/lib/openfoodfacts/locale.rb +15 -12
- data/lib/openfoodfacts/mission.rb +3 -2
- data/lib/openfoodfacts/press.rb +14 -24
- data/lib/openfoodfacts/product.rb +6 -5
- data/lib/openfoodfacts/version.rb +1 -1
- data/test/minitest_helper.rb +7 -1
- data/test/test_openfoodfacts.rb +8 -6
- metadata +22 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8ee85e6766c13c0afa60c4800d43c99c85282f3544427d725cee0a97023631d9
|
4
|
+
data.tar.gz: 054c0a1972297b84f91b7c3d3d96006655d29f755f781800ec80808b297e840f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e9a7773561119e9b32f16677848dd28b54ce4c31f740d5a1f7b3f9592c6798d739d2815030bd507a4ed8df318f30f3fcaf06f26700f36dd26b67f45e2280099
|
7
|
+
data.tar.gz: d188187e2245d87ef1bd051485212f24bce554d7f9add603559617bea6353831535f21dcac65cc008b21492cf50ebdf0b3006359fcf531f7b0bd0ea3d51df5c5
|
data/README.md
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
[](https://badge.fury.io/rb/openfoodfacts)
|
4
4
|
[](https://travis-ci.org/openfoodfacts/openfoodfacts-ruby)
|
5
|
+
[](https://ci.appveyor.com/project/nicolasleger/openfoodfacts-ruby/branch/master)
|
5
6
|
[](https://gemnasium.com/openfoodfacts/openfoodfacts-ruby)
|
6
7
|
[](https://codeclimate.com/github/openfoodfacts/openfoodfacts-ruby)
|
7
8
|
[](https://coveralls.io/github/openfoodfacts/openfoodfacts-ruby?branch=master)
|
data/lib/openfoodfacts/faq.rb
CHANGED
@@ -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')
|
data/lib/openfoodfacts/locale.rb
CHANGED
@@ -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
|
-
|
12
|
-
|
13
|
-
|
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
|
-
|
16
|
-
|
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
|
30
|
+
# Return locale from pair
|
28
31
|
#
|
29
|
-
def
|
30
|
-
|
32
|
+
def locale_from_pair(pair, domain: DEFAULT_DOMAIN)
|
33
|
+
code = pair.first
|
31
34
|
{
|
32
|
-
"name" =>
|
33
|
-
"code" =>
|
34
|
-
"url" => "https://#{
|
35
|
-
} if
|
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
|
data/lib/openfoodfacts/press.rb
CHANGED
@@ -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:
|
19
|
+
def items(locale: 'fr', domain: DEFAULT_DOMAIN)
|
26
20
|
if path = LOCALE_PATHS[locale]
|
27
|
-
|
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('#
|
26
|
+
titles = dom.css('#press_table tbody tr')
|
31
27
|
titles.each_with_index.map do |item, index|
|
32
|
-
|
28
|
+
colums = item.css('td')
|
33
29
|
|
34
|
-
link =
|
30
|
+
link = colums[1].css('a')
|
35
31
|
attributes = {
|
36
|
-
"
|
37
|
-
"
|
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|
|
data/test/minitest_helper.rb
CHANGED
@@ -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
|
data/test/test_openfoodfacts.rb
CHANGED
@@ -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
|
107
|
-
|
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
|
-
|
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/
|
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/
|
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/
|
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.
|
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:
|
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
|
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
|
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: '
|
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: '
|
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: '
|
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: '
|
116
|
+
version: '3.11'
|
111
117
|
description: Open Food Facts API Wrapper, the open database about food.
|
112
118
|
email:
|
113
|
-
-
|
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.
|
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
|
-
|
173
|
-
|
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: []
|