openfoodfacts 0.2.2 → 0.3.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.
@@ -0,0 +1,33 @@
1
+ require 'hashie'
2
+
3
+ module Openfoodfacts
4
+ class ManufacturingPlace < Hashie::Mash
5
+
6
+ # TODO: Add more locales
7
+ LOCALE_PATHS = {
8
+ 'fr' => 'lieux-de-fabrication',
9
+ 'uk' => 'manufacturing-places',
10
+ 'us' => 'manufacturing-places',
11
+ 'world' => 'manufacturing-places'
12
+ }
13
+
14
+ class << self
15
+
16
+ # Get manufacturing places
17
+ #
18
+ def all(locale: Openfoodfacts::DEFAULT_LOCALE)
19
+ if path = LOCALE_PATHS[locale]
20
+ Product.tags_from_page(self, "http://#{locale}.openfoodfacts.org/#{path}")
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ # Get products from manufacturing place
27
+ #
28
+ def products(page: -1)
29
+ Product.from_website_page(url, page: page, products_count: products_count) if url
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ require 'hashie'
2
+
3
+ module Openfoodfacts
4
+ class Origin < Hashie::Mash
5
+
6
+ # TODO: Add more locales
7
+ LOCALE_PATHS = {
8
+ 'fr' => 'origines',
9
+ 'uk' => 'origins',
10
+ 'us' => 'origins',
11
+ 'world' => 'origins'
12
+ }
13
+
14
+ class << self
15
+
16
+ # Get origins
17
+ #
18
+ def all(locale: Openfoodfacts::DEFAULT_LOCALE)
19
+ if path = LOCALE_PATHS[locale]
20
+ Product.tags_from_page(self, "http://#{locale}.openfoodfacts.org/#{path}")
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ # Get products with origin
27
+ #
28
+ def products(page: -1)
29
+ Product.from_website_page(url, page: page, products_count: products_count) if url
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ require 'hashie'
2
+
3
+ module Openfoodfacts
4
+ class PackagerCode < Hashie::Mash
5
+
6
+ # TODO: Add more locales
7
+ LOCALE_PATHS = {
8
+ 'fr' => 'codes-emballeurs',
9
+ 'uk' => 'packager-codes',
10
+ 'us' => 'packager-codes',
11
+ 'world' => 'packager-codes'
12
+ }
13
+
14
+ class << self
15
+
16
+ # Get packager codes
17
+ #
18
+ def all(locale: Openfoodfacts::DEFAULT_LOCALE)
19
+ if path = LOCALE_PATHS[locale]
20
+ Product.tags_from_page(self, "http://#{locale}.openfoodfacts.org/#{path}")
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ # Get products with packager code
27
+ #
28
+ def products(page: -1)
29
+ Product.from_website_page(url, page: page, products_count: products_count) if url
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ require 'hashie'
2
+
3
+ module Openfoodfacts
4
+ class Packaging < Hashie::Mash
5
+
6
+ # TODO: Add more locales
7
+ LOCALE_PATHS = {
8
+ 'fr' => 'conditionnements',
9
+ 'uk' => 'packaging',
10
+ 'us' => 'packaging',
11
+ 'world' => 'packaging'
12
+ }
13
+
14
+ class << self
15
+
16
+ # Get packagings
17
+ #
18
+ def all(locale: Openfoodfacts::DEFAULT_LOCALE)
19
+ if path = LOCALE_PATHS[locale]
20
+ Product.tags_from_page(self, "http://#{locale}.openfoodfacts.org/#{path}")
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ # Get products with packaging
27
+ #
28
+ def products(page: -1)
29
+ Product.from_website_page(url, page: page, products_count: products_count) if url
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,56 @@
1
+ require 'hashie'
2
+ require 'nokogiri'
3
+ require 'open-uri'
4
+ require 'time'
5
+
6
+ module Openfoodfacts
7
+ class Press < Hashie::Mash
8
+
9
+ # TODO: Add more locales
10
+ LOCALE_PATHS = {
11
+ 'fr' => 'presse',
12
+ 'uk' => 'press',
13
+ 'us' => 'press',
14
+ 'world' => 'press'
15
+ }
16
+
17
+ LOCALE_DATE_FORMATS = {
18
+ 'fr' => '%d/%m/%Y',
19
+ 'uk' => '%m/%d/%Y',
20
+ 'us' => '%m/%d/%Y',
21
+ 'world' => '%m/%d/%Y'
22
+ }
23
+
24
+ class << self
25
+ def items(locale: Openfoodfacts::DEFAULT_LOCALE)
26
+ if path = LOCALE_PATHS[locale]
27
+ html = open("http://#{locale}.openfoodfacts.org/#{path}").read
28
+ dom = Nokogiri::HTML.fragment(html)
29
+
30
+ titles = dom.css('#main_column li')
31
+ titles.each_with_index.map do |item, index|
32
+ data = item.inner_html.split(' - ')
33
+
34
+ link = Nokogiri::HTML.fragment(data.first).css('a')
35
+ attributes = {
36
+ "title" => link.text.strip,
37
+ "url" => link.attr('href').value
38
+ }
39
+
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
+ new(attributes)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ end
56
+ end
@@ -5,6 +5,14 @@ require 'open-uri'
5
5
 
6
6
  module Openfoodfacts
7
7
  class Product < Hashie::Mash
8
+
9
+ # TODO: Add more locales
10
+ LOCALE_WEBURL_PREFIXES = {
11
+ 'fr' => 'produit',
12
+ 'uk' => 'product',
13
+ 'us' => 'product',
14
+ 'world' => 'product'
15
+ }
8
16
 
9
17
  class << self
10
18
 
@@ -24,12 +32,13 @@ module Openfoodfacts
24
32
  # Return product API URL
25
33
  #
26
34
  def url(code, locale: Openfoodfacts::DEFAULT_LOCALE)
27
- "http://#{locale}.openfoodfacts.org/api/v0/produit/#{code}.json"
35
+ "http://#{locale}.openfoodfacts.org/api/v0/produit/#{code}.json" if code
28
36
  end
29
37
 
30
38
  # Search products
31
39
  #
32
40
  def search(terms, locale: Openfoodfacts::DEFAULT_LOCALE, page: 1, page_size: 20, sort_by: 'unique_scans_n')
41
+ terms = URI::encode(terms)
33
42
  url = "http://#{locale}.openfoodfacts.org/cgi/search.pl?search_terms=#{terms}&jqm=1&page=#{page}&page_size=#{page_size}&sort_by=#{sort_by}"
34
43
  json = open(url).read
35
44
  hash = JSON.parse(json)
@@ -71,6 +80,49 @@ module Openfoodfacts
71
80
  from_html_list(html, 'ul.products li', /\/(\d+)[\/|\Z]/i)
72
81
  end
73
82
 
83
+ # page -1 to fetch all pages
84
+ def from_website_page(page_url, page: -1, products_count: nil)
85
+ if page == -1
86
+ if products_count # Avoid one call
87
+ pages_count = (products_count.to_f / 20).ceil
88
+ (1..pages_count).map { |page| from_website_page(page_url, page: page) }.flatten
89
+ else
90
+ products = []
91
+
92
+ page = 1
93
+ begin
94
+ products_on_page = from_website_page(page_url, page: page)
95
+ products += products_on_page
96
+ page += 1
97
+ end while products_on_page.any?
98
+
99
+ products
100
+ end
101
+ else
102
+ html = open("#{page_url}/#{page}").read
103
+ from_website_list(html)
104
+ end
105
+ end
106
+
107
+ def tags_from_page(_klass, page_url, &custom_tag_parsing)
108
+ html = open(page_url).read
109
+ dom = Nokogiri::HTML.fragment(html)
110
+
111
+ dom.css('table#tagstable tbody tr').map do |tag|
112
+ if custom_tag_parsing
113
+ custom_tag_parsing.call(tag)
114
+ else
115
+ link = tag.css('a').first
116
+
117
+ _klass.new({
118
+ "name" => link.text.strip,
119
+ "url" => URI.join(page_url, link.attr('href')).to_s,
120
+ "products_count" => tag.css('td')[1].text.to_i
121
+ })
122
+ end
123
+ end
124
+ end
125
+
74
126
  end
75
127
 
76
128
  # Fetch product
@@ -111,5 +163,15 @@ module Openfoodfacts
111
163
  self.class.url(self.code, locale: locale)
112
164
  end
113
165
 
166
+ # Return Product web URL according to locale
167
+ #
168
+ def weburl(locale: nil)
169
+ locale ||= self.lc || Openfoodfacts::DEFAULT_LOCALE
170
+
171
+ if self.code && prefix = LOCALE_WEBURL_PREFIXES[locale]
172
+ "http://#{locale}.openfoodfacts.org/#{prefix}/#{self.code}"
173
+ end
174
+ end
175
+
114
176
  end
115
177
  end
@@ -1,27 +1,23 @@
1
1
  require 'hashie'
2
- require 'nokogiri'
3
- require 'open-uri'
4
2
 
5
3
  module Openfoodfacts
6
4
  class ProductState < Hashie::Mash
7
5
 
6
+ # TODO: Add more locales
7
+ LOCALE_PATHS = {
8
+ 'fr' => 'etats',
9
+ 'uk' => 'states',
10
+ 'us' => 'states',
11
+ 'world' => 'states'
12
+ }
13
+
8
14
  class << self
9
15
 
10
16
  # Get product states
11
17
  #
12
- def all
13
- url = "http://world.openfoodfacts.org/states"
14
- html = open(url).read
15
- dom = Nokogiri::HTML.fragment(html)
16
-
17
- dom.css('table#tagstable tbody tr').map do |product_state|
18
- link = product_state.css('a').first
19
-
20
- new({
21
- "name" => link.text.strip,
22
- "url" => URI.join(url, link.attr('href')).to_s,
23
- "products_count" => product_state.css('td').last.text.to_i
24
- })
18
+ def all(locale: Openfoodfacts::DEFAULT_LOCALE)
19
+ if path = LOCALE_PATHS[locale]
20
+ Product.tags_from_page(self, "http://#{locale}.openfoodfacts.org/#{path}")
25
21
  end
26
22
  end
27
23
 
@@ -30,19 +26,7 @@ module Openfoodfacts
30
26
  # Get products with state
31
27
  #
32
28
  def products(page: -1)
33
- if url
34
- if page == -1
35
- if products_count
36
- pages_count = (products_count.to_f / 20).ceil
37
- (1..pages_count).map { |page| products(page: page) }.flatten
38
- end
39
- else
40
- page_url = "#{url}/#{page}"
41
- html = open(page_url).read
42
-
43
- Product.from_website_list(html)
44
- end
45
- end
29
+ Product.from_website_page(url, page: page, products_count: products_count) if url
46
30
  end
47
31
 
48
32
  end
@@ -0,0 +1,33 @@
1
+ require 'hashie'
2
+
3
+ module Openfoodfacts
4
+ class PurchasePlace < Hashie::Mash
5
+
6
+ # TODO: Add more locales
7
+ LOCALE_PATHS = {
8
+ 'fr' => 'lieux-de-vente',
9
+ 'uk' => 'purchase-places',
10
+ 'us' => 'purchase-places',
11
+ 'world' => 'purchase-places'
12
+ }
13
+
14
+ class << self
15
+
16
+ # Get purchase places
17
+ #
18
+ def all(locale: Openfoodfacts::DEFAULT_LOCALE)
19
+ if path = LOCALE_PATHS[locale]
20
+ Product.tags_from_page(self, "http://#{locale}.openfoodfacts.org/#{path}")
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ # Get products with purchase place
27
+ #
28
+ def products(page: -1)
29
+ Product.from_website_page(url, page: page, products_count: products_count) if url
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ require 'hashie'
2
+
3
+ module Openfoodfacts
4
+ class Store < Hashie::Mash
5
+
6
+ # TODO: Add more locales
7
+ LOCALE_PATHS = {
8
+ 'fr' => 'magasins',
9
+ 'uk' => 'stores',
10
+ 'us' => 'stores',
11
+ 'world' => 'stores'
12
+ }
13
+
14
+ class << self
15
+
16
+ # Get stores
17
+ #
18
+ def all(locale: Openfoodfacts::DEFAULT_LOCALE)
19
+ if path = LOCALE_PATHS[locale]
20
+ Product.tags_from_page(self, "http://#{locale}.openfoodfacts.org/#{path}")
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ # Get products from store
27
+ #
28
+ def products(page: -1)
29
+ Product.from_website_page(url, page: page, products_count: products_count) if url
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,33 @@
1
+ require 'hashie'
2
+
3
+ module Openfoodfacts
4
+ class Trace < Hashie::Mash
5
+
6
+ # TODO: Add more locales
7
+ LOCALE_PATHS = {
8
+ 'fr' => 'traces',
9
+ 'uk' => 'traces',
10
+ 'us' => 'traces',
11
+ 'world' => 'traces'
12
+ }
13
+
14
+ class << self
15
+
16
+ # Get traces
17
+ #
18
+ def all(locale: Openfoodfacts::DEFAULT_LOCALE)
19
+ if path = LOCALE_PATHS[locale]
20
+ Product.tags_from_page(self, "http://#{locale}.openfoodfacts.org/#{path}")
21
+ end
22
+ end
23
+
24
+ end
25
+
26
+ # Get products with trace
27
+ #
28
+ def products(page: -1)
29
+ Product.from_website_page(url, page: page, products_count: products_count) if url
30
+ end
31
+
32
+ end
33
+ end