Repository: openfoodfacts/openfoodfacts-python

Issue:
Make it possible to create an Open Beauty Facts variant

Discussion:

Patch:
diff --git a/openfoodfacts/__init__.py b/openfoodfacts/__init__.py
index a891bf3..ff63f77 100644
--- a/openfoodfacts/__init__.py
+++ b/openfoodfacts/__init__.py
@@ -3,6 +3,7 @@ import sys
 from . import facets
 from . import utils
 from .products import get_product
+from . import openbeautyfacts
 
 openfoodfacts = sys.modules[__name__]
 __version__ = '0.0.1'
diff --git a/openfoodfacts/facets.py b/openfoodfacts/facets.py
index cc00cb9..0b2f78e 100644
--- a/openfoodfacts/facets.py
+++ b/openfoodfacts/facets.py
@@ -11,8 +11,8 @@ facets = [
     'label',
     'languages',
     'nutrition_grade',
-    'packagings',
-    'packager_code',
+    'packaging',
+    'packaging_codes',
     'purchase_places',
     'photographer',
     'informer',
diff --git a/openfoodfacts/openbeautyfacts.py b/openfoodfacts/openbeautyfacts.py
new file mode 100644
index 0000000..dd2f8c4
--- /dev/null
+++ b/openfoodfacts/openbeautyfacts.py
@@ -0,0 +1,57 @@
+# -*- coding: utf-8 -*-
+import requests
+from . import utils
+
+
+def get_product(barcode, locale='world'):
+    """
+    Return information of a given product.
+    """
+    return utils.fetch(utils.build_url(geography=locale,
+                                       service='api',
+                                       resource_type='product',
+                                       parameters=barcode,
+                                       entity="beauty"))
+
+
+def get_by_facets(query, page=1, locale='world'):
+    """
+    Return products for a set of facets.
+    """
+    path = []
+    keys = query.keys()
+
+    if len(keys) == 0:
+        return []
+
+    else:
+        keys = sorted(keys)
+        for key in keys:
+            path.append(key)
+            path.append(query[key])
+
+        return utils. \
+            fetch(utils.build_url(geography=locale,
+                                  resource_type=path,
+                                  parameters=str(page),
+                                  entity="beauty"))['products']
+
+
+def search(query, page=1, page_size=20,
+           sort_by='unique_scans', locale='world'):
+    """
+    Perform a search using Open Food Facts search engine.
+    """
+    parameters = {'search_terms': query,
+                  'page': page,
+                  'page_size': page_size,
+                  'sort_by': sort_by,
+                  'json': '1'}
+
+    path = utils.build_url(geography=locale,
+                           service='cgi',
+                           resource_type='search.pl',
+                           parameters=parameters,
+                           entity="beauty")
+
+    return utils.fetch(path, json_file=False)
diff --git a/openfoodfacts/utils.py b/openfoodfacts/utils.py
index 4601e6d..e8d5f99 100644
--- a/openfoodfacts/utils.py
+++ b/openfoodfacts/utils.py
@@ -5,6 +5,7 @@ import sys
 import urllib
 
 API_URL = "https://%s.openfoodfacts.org/"
+OBF_API_URL = "https://%s.openbeautyfacts.org/"
 
 
 def login_into_OFF():
@@ -62,9 +63,16 @@ def download_data(file_type='mongodb'):
 
 
 def build_url(geography='world', service=None,
-              resource_type=None, parameters=None):
+              resource_type=None, parameters=None, entity="food"):
 
-    geo_url = API_URL % (geography)
+    if entity == "food":
+        geo_url = API_URL % (geography)
+
+    elif entity == "beauty":
+        geo_url = OBF_API_URL % (geography)
+
+    else:
+        raise ValueError("Product not recognized!")
 
     geo_url = geo_url[:-1]
 


Test patch:
diff --git a/tests/facets_test.py b/tests/facets_test.py
index b54228a..8d4e5c6 100644
--- a/tests/facets_test.py
+++ b/tests/facets_test.py
@@ -10,15 +10,35 @@ class TestFacets(unittest.TestCase):
             mock.get('https://world.openfoodfacts.org/traces.json',
                      text='{"tags":["egg"]}')
             res = openfoodfacts.facets.get_traces()
-            self.assertEquals(res, ["egg"])
+            self.assertEqual(res, ["egg"])
 
     def test_get_additives(self):
         with requests_mock.mock() as mock:
             mock.get('https://world.openfoodfacts.org/additives.json',
                      text='{"tags":["additive"]}')
             res = openfoodfacts.facets.get_additives()
-            self.assertEquals(res, ["additive"])
+            self.assertEqual(res, ["additive"])
 
+    def test_get_purchase_places(self):
+        with requests_mock.mock() as mock:
+            mock.get('https://world.openfoodfacts.org/purchase-places.json',
+                     text='{"tags":["France"]}')
+            res = openfoodfacts.facets.get_purchase_places()
+            self.assertEqual(res, ["France"])
+
+    def test_get_packaging_codes(self):
+        with requests_mock.mock() as mock:
+            mock.get('https://world.openfoodfacts.org/packager-codes.json',
+                     text='{"tags":["FABRICANTE-Y-ENVASADOR"]}')
+            res = openfoodfacts.facets.get_packaging_codes()
+            self.assertEqual(res, ["FABRICANTE-Y-ENVASADOR"])
+
+    def test_get_entry_dates(self):
+        with requests_mock.mock() as mock:
+            mock.get('https://world.openfoodfacts.org/entry-dates.json',
+                     text='{"tags":["2017"]}')
+            res = openfoodfacts.facets.get_entry_dates()
+            self.assertEqual(res, ["2017"])
 
 if __name__ == '__main__':
     unittest.main()
diff --git a/tests/products_test.py b/tests/products_test.py
index a2c3ab9..1bf702c 100644
--- a/tests/products_test.py
+++ b/tests/products_test.py
@@ -13,32 +13,32 @@ class TestProducts(unittest.TestCase):
                 'https://world.openfoodfacts.org/api/v0/product/1223435.json',
                 text='{"name":"product_test"}')
             res = openfoodfacts.get_product('1223435')
-            self.assertEquals(res, {'name': 'product_test'})
+            self.assertEqual(res, {'name': 'product_test'})
 
     def test_get_by_trace(self):
         with requests_mock.mock() as mock:
             mock.get('https://world.openfoodfacts.org/trace/egg/1.json',
                      text='{"products":["omelet"]}')
             res = openfoodfacts.products.get_by_trace('egg')
-            self.assertEquals(res, ["omelet"])
+            self.assertEqual(res, ["omelet"])
 
     def test_get_by_trace_pagination(self):
         with requests_mock.mock() as mock:
             mock.get('https://world.openfoodfacts.org/trace/egg/2.json',
                      text='{"products":["omelet"]}')
             res = openfoodfacts.products.get_by_trace('egg', 2)
-            self.assertEquals(res, ["omelet"])
+            self.assertEqual(res, ["omelet"])
 
     def test_get_by_country(self):
         with requests_mock.mock() as mock:
             mock.get('https://world.openfoodfacts.org/country/france/1.json',
                      text='{"products":["omelet"]}')
             res = openfoodfacts.products.get_by_country('france')
-            self.assertEquals(res, ["omelet"])
+            self.assertEqual(res, ["omelet"])
 
     def test_get_by_country_and_trace(self):
         res = openfoodfacts.products.get_by_facets({})
-        self.assertEquals(res, [])
+        self.assertEqual(res, [])
 
         with requests_mock.mock() as mock:
             mock.get(
@@ -47,7 +47,7 @@ class TestProducts(unittest.TestCase):
                 text='{"products":["omelet"]}')
             res = openfoodfacts.products.get_by_facets(
                     {'trace': 'egg', 'country': 'france'})
-            self.assertEquals(res, ["omelet"])
+            self.assertEqual(res, ["omelet"])
 
     def test_search(self):
         with requests_mock.mock() as mock:
@@ -57,7 +57,7 @@ class TestProducts(unittest.TestCase):
                 '1&page_size=20&sort_by=unique_scans',
                 text='{"products":["kinder bueno"], "count": 1}')
             res = openfoodfacts.products.search('kinder bueno')
-            self.assertEquals(res["products"],  ["kinder bueno"])
+            self.assertEqual(res["products"],  ["kinder bueno"])
             mock.get(
                 'https://world.openfoodfacts.org/cgi/search.pl?' +
                 'search_terms=banania&json=1&page=' +
@@ -65,7 +65,30 @@ class TestProducts(unittest.TestCase):
                 text='{"products":["banania", "banania big"], "count": 2}')
             res = openfoodfacts.products.search(
                 'banania', page=2, page_size=10)
-            self.assertEquals(res["products"],  ["banania", "banania big"])
+            self.assertEqual(res["products"],  ["banania", "banania big"])
+
+    def test_advanced_search(self):
+        with requests_mock.mock() as mock:
+            mock.get(
+                'https://world.openfoodfacts.org/cgi/search.pl?' +
+                'search_terms=coke&tagtype_0=packaging&' +
+                'tag_contains_0=contains&tag_0=plastic&' +
+                'nutriment_0=energy&nutriment_compare_0=gt&' +
+                'nutriment_value_0=0&sort_by=unique_scans&' +
+                'page_size=20',
+                text= '{"products":["Diet Coke"], "count": 1}')
+            res = openfoodfacts.products.advanced_search({
+                  "search_terms":"coke",
+                  "tagtype_0":"packaging",
+                  "tag_contains_0":"contains",
+                  "tag_0":"plastic",
+                  "nutriment_0":"energy",
+                  "nutriment_compare_0":"gt",
+                  "nutriment_value_0":"0",
+                  "sort_by":"unique_scans",
+                  "page_size":"20"
+                })
+            self.assertEqual(res["products"],["Diet Coke"])
 
 if __name__ == '__main__':
     unittest.main()