Repository: hhursev/recipe-scrapers
Pull request #416 (2021-07-24 20:27:55)

Feature/added category and prep cook time
This code allows to get prep_time, cook_time and category from schema recipe, if exists.


Patch:
diff --git a/recipe_scrapers/_abstract.py b/recipe_scrapers/_abstract.py
index be860abb..cff26157 100644
--- a/recipe_scrapers/_abstract.py
+++ b/recipe_scrapers/_abstract.py
@@ -61,8 +61,19 @@ class AbstractScraper:
     def title(self):
         raise NotImplementedError("This should be implemented.")
 
+    def category(self):
+        raise NotImplementedError("This should be implemented.")
+
     def total_time(self):
-        """total time it takes to preparate the recipe in minutes"""
+        """total time it takes to preparate and cook the recipe in minutes"""
+        raise NotImplementedError("This should be implemented.")
+
+    def cook_time(self):
+        """cook time of the recipe in minutes"""
+        raise NotImplementedError("This should be implemented.")
+
+    def prep_time(self):
+        """preparation time of the recipe in minutes"""
         raise NotImplementedError("This should be implemented.")
 
     def yields(self):
diff --git a/recipe_scrapers/_exceptions.py b/recipe_scrapers/_exceptions.py
index f9ff73a8..22def249 100644
--- a/recipe_scrapers/_exceptions.py
+++ b/recipe_scrapers/_exceptions.py
@@ -11,6 +11,7 @@ class WebsiteNotImplementedError(RecipeScrapersExceptions):
     """Error when website is not supported by this library."""
 
     def __init__(self, domain):
+        self.domain = domain
         message = f"Website ({self.domain}) not supported."
         super().__init__(message)
 
@@ -19,8 +20,8 @@ class NoSchemaFoundInWildMode(RecipeScrapersExceptions):
     """Error when wild_mode fails to locate schema at the url"""
 
     def __init__(self, url):
-        message = f"No Recipe Schema found at {self.url}."
         self.url = url
+        message = f"No Recipe Schema found at {self.url}."
         super().__init__(message)
 
 
diff --git a/recipe_scrapers/_factory.py b/recipe_scrapers/_factory.py
index a09c91ae..1a0a71cc 100644
--- a/recipe_scrapers/_factory.py
+++ b/recipe_scrapers/_factory.py
@@ -10,9 +10,18 @@ class SchemaScraperFactory:
         def title(self):
             return self.schema.title()
 
+        def category(self):
+            return self.schema.category()
+
         def total_time(self):
             return self.schema.total_time()
 
+        def cook_time(self):
+            return self.schema.cook_time()
+
+        def prep_time(self):
+            return self.schema.prep_time()
+
         def yields(self):
             return self.schema.yields()
 
diff --git a/recipe_scrapers/_schemaorg.py b/recipe_scrapers/_schemaorg.py
index 52e14287..cf306d09 100644
--- a/recipe_scrapers/_schemaorg.py
+++ b/recipe_scrapers/_schemaorg.py
@@ -51,6 +51,12 @@ class SchemaOrg:
     def title(self):
         return normalize_string(self.data.get("name"))
 
+    def category(self):
+        cuisine = self.data.get("recipeCategory")
+        if isinstance(cuisine, list):
+            return ",".join(cuisine)
+        return cuisine
+
     def author(self):
         author = self.data.get("author")
         if (
@@ -77,6 +83,16 @@ class SchemaOrg:
             total_time = sum(times)
         return total_time
 
+    def cook_time(self):
+        if not (self.data.keys() & {"cookTime"}):
+            raise SchemaOrgException("Cooktime information not found in SchemaOrg")
+        return get_minutes(self.data.get("cookTime"), return_zero_on_not_found=True)
+
+    def prep_time(self):
+        if not (self.data.keys() & {"prepTime"}):
+            raise SchemaOrgException("Preptime information not found in SchemaOrg")
+        return get_minutes(self.data.get("prepTime"), return_zero_on_not_found=True)
+
     def yields(self):
         yield_data = self.data.get("recipeYield")
         if yield_data and isinstance(yield_data, list):
@@ -180,6 +196,8 @@ class SchemaOrg:
 
     def cuisine(self):
         cuisine = self.data.get("recipeCuisine")
-        if isinstance(cuisine, list):
+        if cuisine is None:
+            raise SchemaOrgException("No cuisine data in SchemaOrg.")
+        elif isinstance(cuisine, list):
             return ",".join(cuisine)
         return cuisine


Test patch:
diff --git a/tests/library/test_exceptions.py b/tests/library/test_exceptions.py
new file mode 100644
index 00000000..303e6983
--- /dev/null
+++ b/tests/library/test_exceptions.py
@@ -0,0 +1,19 @@
+import unittest
+
+from recipe_scrapers import (
+    NoSchemaFoundInWildMode,
+    WebsiteNotImplementedError,
+    scrape_me,
+)
+
+
+class TestExceptions(unittest.TestCase):
+    def test_WebsiteNotImplementedError(self):
+        with self.assertRaises(WebsiteNotImplementedError):
+            scrape_me("https://example.com/recipe")
+
+    def test_NoSchemaFoundInWildMode(self):
+        exception = NoSchemaFoundInWildMode("example.com")
+
+        self.assertEquals(exception.url, "example.com")
+        self.assertEquals(exception.message, "No Recipe Schema found at example.com.")