def scrape_image(image_url: str, slug: str) -> Path: logger.info(f"Image URL: {image_url}") if isinstance(image_url, str): # Handles String Types image_url = image_url if isinstance(image_url, list): # Handles List Types image_url = image_url[0] if isinstance(image_url, dict): # Handles Dictionary Types for key in image_url: if key == "url": image_url = image_url.get("url") filename = slug + "." + image_url.split(".")[-1] filename = Recipe(slug=slug).image_dir.joinpath(filename) try: r = requests.get(image_url, stream=True) except Exception: logger.exception("Fatal Image Request Exception") return None if r.status_code == 200: r.raw.decode_content = True logger.info(f"File Name Suffix {filename.suffix}") write_image(slug, r.raw, filename.suffix) filename.unlink(missing_ok=True) return slug return None
def import_recipes(recipe_dir: Path) -> Recipe: image = False for file in recipe_dir.glob("full.*"): image = file break for file in recipe_dir.glob("*.json"): recipe_file = file break with open(recipe_file, "r") as f: recipe_dict = json.loads(f.read()) recipe_data = Cleaner.clean(recipe_dict) image_name = recipe_data["slug"] recipe_data["image"] = recipe_data["slug"] recipe_data["tags"] = clean_nextcloud_tags(recipe_data.get("keywords")) recipe = Recipe(**recipe_data) if image: shutil.copy(image, app_dirs.IMG_DIR.joinpath(image_name + image.suffix)) return recipe
def clean_recipe_dictionary(self, recipe_dict) -> Recipe: """Calls the rewrite_alias function and the Cleaner.clean function on a dictionary and returns the result unpacked into a Recipe object""" recipe_dict = self.rewrite_alias(recipe_dict) recipe_dict = cleaner.clean(recipe_dict, url=recipe_dict.get("org_url", None)) return Recipe(**recipe_dict)
def create_from_json( data: Recipe, session: Session = Depends(generate_session), current_user=Depends(get_current_user), ) -> str: """ Takes in a JSON string and loads data into the database as a new entry""" recipe: Recipe = db.recipes.create(session, data.dict()) return recipe.slug
def write_image(recipe_slug: str, file_data: bytes, extension: str) -> Path: image_dir = Recipe(slug=recipe_slug).image_dir extension = extension.replace(".", "") image_path = image_dir.joinpath(f"original.{extension}") image_path.unlink(missing_ok=True) if isinstance(file_data, Path): shutil.copy2(file_data, image_path) elif isinstance(file_data, bytes): with open(image_path, "ab") as f: f.write(file_data) else: with open(image_path, "ab") as f: shutil.copyfileobj(file_data, f) print(image_path) minify.minify_image(image_path, force=True) return image_path
def move_all_images(): for image_file in app_dirs.IMG_DIR.iterdir(): if image_file.is_file(): if image_file.name == ".DS_Store": continue new_folder = app_dirs.IMG_DIR.joinpath(image_file.stem) new_folder.mkdir(parents=True, exist_ok=True) new_file = new_folder.joinpath(f"original{image_file.suffix}") if new_file.is_file(): new_file.unlink() image_file.rename(new_file) if image_file.is_dir(): slug = image_file.name image_file.rename(Recipe(slug=slug).image_dir)
def update_recipe( recipe_slug: str, data: Recipe, session: Session = Depends(generate_session), current_user=Depends(get_current_user), ): """ Updates a recipe by existing slug and data. """ recipe: Recipe = db.recipes.update(session, recipe_slug, data.dict()) if recipe_slug != recipe.slug: rename_image(original_slug=recipe_slug, new_slug=recipe.slug) return recipe.slug
def create_from_url(url: str) -> Recipe: """Main entry point for generating a recipe from a URL. Pass in a URL and a Recipe object will be returned if successful. Args: url (str): a valid string representing a URL Returns: Recipe: Recipe Object """ r = requests.get(url) new_recipe = extract_recipe_from_html(r.text, url) new_recipe = Cleaner.clean(new_recipe, url) new_recipe = download_image_for_recipe(new_recipe) return Recipe(**new_recipe)
def read_chowdown_file(recipe_file: Path) -> Recipe: """Parse through the yaml file to try and pull out the relavent information. Some issues occur when ":" are used in the text. I have no put a lot of effort into this so there may be better ways of going about it. Currently, I get about 80-90% of recipes from repos I've tried. Args: recipe_file (Path): Path to the .yml file Returns: Recipe: Recipe class object """ with open(recipe_file, "r") as stream: recipe_description: str = str recipe_data: dict = {} try: for x, item in enumerate(yaml.load_all(stream, Loader=Loader)): if x == 0: recipe_data = item elif x == 1: recipe_description = str(item) except yaml.YAMLError: return reformat_data = { "name": recipe_data.get("title"), "description": recipe_description, "image": recipe_data.get("image", ""), "recipeIngredient": recipe_data.get("ingredients"), "recipeInstructions": recipe_data.get("directions"), "tags": recipe_data.get("tags").split(","), } reformated_list = [{"text": instruction} for instruction in reformat_data["recipeInstructions"]] reformat_data["recipeInstructions"] = reformated_list return Recipe(**reformat_data)
def delete_assets(recipe_slug): recipe_dir = Recipe(slug=recipe_slug).directory rmtree(recipe_dir, ignore_errors=True) logger.info(f"Recipe Directory Removed: {recipe_slug}")