def get_recipe_from_file(self, file): recipe_json = json.loads(file.getvalue().decode("utf-8")) description = '' if len(recipe_json['description'].strip()) > 500 else recipe_json['description'].strip() recipe = Recipe.objects.create( name=recipe_json['name'].strip(), description=description, created_by=self.request.user, internal=True, space=self.request.space) # TODO parse times (given in PT2H3M ) # @vabene check recipe_url_import.iso_duration_to_minutes I think it does what you are looking for ingredients_added = False for s in recipe_json['recipe_instructions']: step = Step.objects.create( instruction=s['text'], space=self.request.space, ) if not ingredients_added: ingredients_added = True if len(recipe_json['description'].strip()) > 500: step.instruction = recipe_json['description'].strip() + '\n\n' + step.instruction ingredient_parser = IngredientParser(self.request, True) for ingredient in recipe_json['recipe_ingredient']: try: if ingredient['food']: f = ingredient_parser.get_food(ingredient['food']) u = ingredient_parser.get_unit(ingredient['unit']) amount = ingredient['quantity'] note = ingredient['note'] else: amount, unit, ingredient, note = ingredient_parser.parse(ingredient['note']) f = ingredient_parser.get_food(ingredient) u = ingredient_parser.get_unit(unit) step.ingredients.add(Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, space=self.request.space, )) except Exception: pass recipe.steps.add(step) for f in self.files: if '.zip' in f['name']: import_zip = ZipFile(f['file']) try: self.import_recipe_image(recipe, BytesIO(import_zip.read(f'recipes/{recipe_json["slug"]}/images/min-original.webp')), filetype=get_filetype(f'recipes/{recipe_json["slug"]}/images/original')) except Exception: pass return recipe
def hook(request, token): try: tb = get_object_or_404(TelegramBot, webhook_token=token) data = json.loads(request.body.decode()) if tb.chat_id == '': tb.chat_id = data['message']['chat']['id'] tb.save() if tb.chat_id == str(data['message']['chat']['id']): request.space = tb.space # TODO this is likely a bad idea. Verify and test request.user = tb.created_by ingredient_parser = IngredientParser(request, False) amount, unit, food, note = ingredient_parser.parse( data['message']['text']) f = ingredient_parser.get_food(food) u = ingredient_parser.get_unit(unit) ShoppingListEntry.objects.create(food=f, unit=u, amount=amount, created_by=request.user, space=request.space) return JsonResponse({'data': data['message']['text']}) except Exception: traceback.print_exc() return JsonResponse({})
def hook(request, token): try: tb = get_object_or_404(TelegramBot, webhook_token=token) data = json.loads(request.body.decode()) if tb.chat_id == '': tb.chat_id = data['message']['chat']['id'] tb.save() if tb.chat_id == str(data['message']['chat']['id']): sl = ShoppingList.objects.filter( Q(created_by=tb.created_by)).filter( finished=False, space=tb.space).order_by('-created_at').first() if not sl: sl = ShoppingList.objects.create(created_by=tb.created_by, space=tb.space) request.space = tb.space # TODO this is likely a bad idea. Verify and test request.user = tb.created_by ingredient_parser = IngredientParser(request, False) amount, unit, ingredient, note = ingredient_parser.parse( data['message']['text']) f = ingredient_parser.get_food(ingredient) u = ingredient_parser.get_unit(unit) sl.entries.add( ShoppingListEntry.objects.create(food=f, unit=u, amount=amount)) return JsonResponse({'data': data['message']['text']}) except Exception: pass return JsonResponse({})
def get_recipe_from_file(self, file): ingredient_mode = False direction_mode = False ingredients = [] directions = [] for line in file.replace('\r', '').replace('\n\n', '\n').split('\n'): if 'Titel:' in line: title = line.replace('Titel:', '').strip() if 'Kategorien:' in line: tags = line.replace('Kategorien:', '').strip() if ingredient_mode and ('quelle' in line.lower() or 'source' in line.lower() or (line == '' and len(ingredients) > 0)): ingredient_mode = False direction_mode = True if ingredient_mode: if line != '' and '===' not in line and 'Zubereitung' not in line: ingredients.append(line.strip()) if direction_mode: if line.strip() != '' and line.strip() != '=====': directions.append(line.strip()) if 'Zutaten:' in line or 'Ingredients' in line or 'Menge:' in line: ingredient_mode = True recipe = Recipe.objects.create(name=title, created_by=self.request.user, internal=True, space=self.request.space) for k in tags.split(','): keyword, created = Keyword.objects.get_or_create( name=k.strip(), space=self.request.space) recipe.keywords.add(keyword) step = Step.objects.create( instruction=' \n'.join(directions) + '\n\n', space=self.request.space, ) ingredient_parser = IngredientParser(self.request, True) for ingredient in ingredients: if len(ingredient.strip()) > 0: amount, unit, food, note = ingredient_parser.parse(ingredient) f = ingredient_parser.get_food(food) u = ingredient_parser.get_unit(unit) step.ingredients.add( Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space, )) recipe.steps.add(step) return recipe
def get_recipe_from_file(self, file): servings = 1 ingredients = [] directions = [] for line in file.replace('\r', '').split('\n'): if not line.startswith('MMMMM') and line.strip != '': if 'Title:' in line: title = line.replace('Title:', '').strip() else: if 'Categories:' in line: tags = line.replace('Categories:', '').strip() else: if 'Yield:' in line: servings_text = line.replace('Yield:', '').strip() else: if re.match('\s{2,}([0-9])+', line): ingredients.append(line.strip()) else: directions.append(line.strip()) try: servings = re.findall('([0-9])+', servings_text)[0] except Exception as e: print('failed parsing servings ', e) recipe = Recipe.objects.create(name=title, servings=servings, created_by=self.request.user, internal=True, space=self.request.space) for k in tags.split(','): keyword, created = Keyword.objects.get_or_create( name=k.strip(), space=self.request.space) recipe.keywords.add(keyword) step = Step.objects.create( instruction='\n'.join(directions) + '\n\n', space=self.request.space, ) ingredient_parser = IngredientParser(self.request, True) for ingredient in ingredients: if len(ingredient.strip()) > 0: amount, unit, ingredient, note = ingredient_parser.parse( ingredient) f = ingredient_parser.get_food(ingredient) u = ingredient_parser.get_unit(unit) step.ingredients.add( Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, space=self.request.space, )) recipe.steps.add(step) return recipe
def get_recipe_from_file(self, file): recipe_html = file.getvalue().decode("utf-8") recipe_json, recipe_tree, html_data, images = get_recipe_from_source( recipe_html, 'CookBookApp', self.request) recipe = Recipe.objects.create(name=recipe_json['name'].strip(), created_by=self.request.user, internal=True, space=self.request.space) try: recipe.servings = re.findall('([0-9])+', recipe_json['recipeYield'])[0] except Exception as e: pass try: recipe.working_time = iso_duration_to_minutes( recipe_json['prepTime']) recipe.waiting_time = iso_duration_to_minutes( recipe_json['cookTime']) except Exception: pass step = Step.objects.create( instruction=recipe_json['recipeInstructions'], space=self.request.space, ) if 'nutrition' in recipe_json: step.instruction = step.instruction + '\n\n' + recipe_json[ 'nutrition'] step.save() recipe.steps.add(step) ingredient_parser = IngredientParser(self.request, True) for ingredient in recipe_json['recipeIngredient']: f = ingredient_parser.get_food(ingredient['ingredient']['text']) u = ingredient_parser.get_unit(ingredient['unit']['text']) step.ingredients.add( Ingredient.objects.create( food=f, unit=u, amount=ingredient['amount'], note=ingredient['note'], space=self.request.space, )) if len(images) > 0: try: response = requests.get(images[0]) self.import_recipe_image(recipe, BytesIO(response.content)) except Exception as e: print('failed to import image ', str(e)) recipe.save() return recipe
def get_recipe_from_file(self, file): source_url = '' ingredient_mode = 0 ingredients = [] directions = [] for i, fl in enumerate(file.readlines(), start=0): line = fl.decode("utf-8") if i == 0: title = line.strip() else: if line.startswith('https:') or line.startswith('http:'): source_url = line.strip() else: if ingredient_mode == 1 and len(line.strip()) == 0: ingredient_mode = 2 if re.match(r'^([0-9])[^.](.)*$', line) and ingredient_mode < 2: ingredient_mode = 1 ingredients.append(line.strip()) else: directions.append(line.strip()) recipe = Recipe.objects.create( name=title, created_by=self.request.user, internal=True, space=self.request.space, ) step = Step.objects.create( instruction='\n'.join(directions), space=self.request.space, ) if source_url != '': step.instruction += '\n' + source_url step.save() ingredient_parser = IngredientParser(self.request, True) for ingredient in ingredients: if len(ingredient.strip()) > 0: amount, unit, ingredient, note = ingredient_parser.parse( ingredient) f = ingredient_parser.get_food(ingredient) u = ingredient_parser.get_unit(unit) step.ingredients.add( Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, space=self.request.space, )) recipe.steps.add(step) return recipe
def get_recipe_from_file(self, file): ingredient_mode = False direction_mode = False ingredients = [] directions = [] for fl in file.readlines(): line = fl.decode("utf-8") if 'Title:' in line: title = line.replace('Title:', '').replace('"', '').strip() if 'Description:' in line: description = line.replace('Description:', '').strip() if 'Original URL:' in line or 'Source:' in line or 'Yield:' in line or 'Total:' in line: if len(line.strip().split(':')[1]) > 0: directions.append(line.strip() + '\n') if ingredient_mode: if len(line) > 2 and 'Instructions:' not in line: ingredients.append(line.strip()) if direction_mode: if len(line) > 2: directions.append(line.strip() + '\n') if 'Ingredients:' in line: ingredient_mode = True if 'Instructions:' in line: ingredient_mode = False direction_mode = True recipe = Recipe.objects.create(name=title, description=description, created_by=self.request.user, internal=True, space=self.request.space) step = Step.objects.create( instruction='\n'.join(directions) + '\n\n', space=self.request.space, ) ingredient_parser = IngredientParser(self.request, True) for ingredient in ingredients: if len(ingredient.strip()) > 0: amount, unit, food, note = ingredient_parser.parse(ingredient) f = ingredient_parser.get_food(food) u = ingredient_parser.get_unit(unit) step.ingredients.add( Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space, )) recipe.steps.add(step) return recipe
def get_recipe_from_file(self, file): recipe = Recipe.objects.create(name=file['name'].strip(), created_by=self.request.user, internal=True, space=self.request.space) try: if file['recipeYield'] != '': recipe.servings = int(file['recipeYield']) if file['totalTime'] != '': recipe.waiting_time = int(file['totalTime']) - int( file['timePrep']) if file['prepTime'] != '': recipe.working_time = int(file['timePrep']) recipe.save() except Exception as e: print('failed to parse yield or time ', str(e)) ingredient_parser = IngredientParser(self.request, True) ingredients_added = False for s in file['recipeInstructions']: step = Step.objects.create( instruction=s['text'], space=self.request.space, ) if not ingredients_added: ingredients_added = True for ingredient in file['recipeIngredient']: amount, unit, food, note = ingredient_parser.parse( ingredient) f = ingredient_parser.get_food(food) u = ingredient_parser.get_unit(unit) step.ingredients.add( Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space, )) recipe.steps.add(step) if len(file['image']) > 0: try: response = requests.get(file['image'][0]) self.import_recipe_image(recipe, BytesIO(response.content)) except Exception as e: print('failed to import image ', str(e)) return recipe
def get_recipe_from_file(self, file): # 'file' comes is as a beautifulsoup object recipe = Recipe.objects.create(name=file.find("h2", {"itemprop": "name"}).text.strip(), created_by=self.request.user, internal=True, space=self.request.space, ) # add 'Courses' and 'Categories' as keywords for course in file.find_all("span", {"itemprop": "recipeCourse"}): keyword, created = Keyword.objects.get_or_create(name=course.text, space=self.request.space) recipe.keywords.add(keyword) for category in file.find_all("meta", {"itemprop": "recipeCategory"}): keyword, created = Keyword.objects.get_or_create(name=category.get("content"), space=self.request.space) recipe.keywords.add(keyword) try: recipe.servings = parse_servings(file.find("span", {"itemprop": "recipeYield"}).text.strip()) recipe.working_time = iso_duration_to_minutes(file.find("span", {"meta": "prepTime"}).text.strip()) recipe.waiting_time = iso_duration_to_minutes(file.find("span", {"meta": "cookTime"}).text.strip()) recipe.save() except AttributeError: pass step = Step.objects.create(instruction='', space=self.request.space,) ingredient_parser = IngredientParser(self.request, True) for ingredient in file.find("div", {"itemprop": "recipeIngredients"}).findChildren("p"): if ingredient.text == "": continue amount, unit, ingredient, note = ingredient_parser.parse(ingredient.text.strip()) f = ingredient_parser.get_food(ingredient) u = ingredient_parser.get_unit(unit) step.ingredients.add(Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, space=self.request.space, )) for s in file.find("div", {"itemprop": "recipeDirections"}).find_all("p"): if s.text == "": continue step.instruction += s.text + ' \n' if file.find("span", {"itemprop": "recipeSource"}).text != '': step.instruction += "\n\nImported from: " + file.find("span", {"itemprop": "recipeSource"}).text step.save() recipe.steps.add(step) # import the Primary recipe image that is stored in the Zip try: for f in self.files: if '.zip' in f['name']: import_zip = ZipFile(f['file']) self.import_recipe_image(recipe, BytesIO(import_zip.read(file.find("img", class_="recipe-photo").get("src"))), filetype='.jpeg') except Exception as e: print(recipe.name, ': failed to import image ', str(e)) return recipe
def get_recipe_from_file(self, file): recipe = Recipe.objects.create(name=file['name'].strip(), created_by=self.request.user, internal=True, space=self.request.space) if file['servings'] != '': recipe.servings = file['servings'] if file['timeCook'] != '': recipe.waiting_time = file['timeCook'] if file['timePrep'] != '': recipe.working_time = file['timePrep'] recipe.save() step = Step.objects.create( instruction=file['directions'], space=self.request.space, ) if file['source'] != '': step.instruction += '\n' + file['source'] ingredient_parser = IngredientParser(self.request, True) for ingredient in file['ingredients'].split('\n'): if len(ingredient.strip()) > 0: amount, unit, food, note = ingredient_parser.parse(ingredient) f = ingredient_parser.get_food(food) u = ingredient_parser.get_unit(unit) step.ingredients.add( Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space, )) recipe.steps.add(step) if file['image'] != '': self.import_recipe_image( recipe, BytesIO( base64.b64decode(file['image'].replace( 'data:image/jpeg;base64,', ''))), filetype='.jpeg') return recipe
def get_recipe_from_file(self, file): recipe = Recipe.objects.create(name=file['name'].strip(), created_by=self.request.user, internal=True, servings=file['servings'], space=self.request.space, waiting_time=file['cook_time'], working_time=file['prep_time']) instructions = '' if file["info"] != '': instructions += file["info"] if file["directions"] != '': instructions += file["directions"] if file["source"] != '': instructions += file["source"] step = Step.objects.create( instruction=instructions, space=self.request.space, ) ingredient_parser = IngredientParser(self.request, True) for ingredient in file['ingredients']: f = ingredient_parser.get_food(ingredient['food']) u = ingredient_parser.get_unit(ingredient['unit']) step.ingredients.add( Ingredient.objects.create( food=f, unit=u, amount=ingredient['amount'], space=self.request.space, )) recipe.steps.add(step) return recipe
def get_recipe_from_file(self, file): recipe_json = json.loads(file.getvalue().decode("utf-8")) description = '' if len(recipe_json['description'].strip( )) > 500 else recipe_json['description'].strip() recipe = Recipe.objects.create(name=recipe_json['name'].strip(), description=description, created_by=self.request.user, internal=True, servings=recipe_json['recipeYield'], space=self.request.space) try: recipe.working_time = iso_duration_to_minutes( recipe_json['prepTime']) recipe.waiting_time = iso_duration_to_minutes( recipe_json['cookTime']) except Exception: pass if 'url' in recipe_json: recipe.source_url = recipe_json['url'].strip() if 'recipeCategory' in recipe_json: try: recipe.keywords.add( Keyword.objects.get_or_create( space=self.request.space, name=recipe_json['recipeCategory'])[0]) except Exception: pass if 'keywords' in recipe_json: try: for x in recipe_json['keywords'].split(','): if x.strip() != '': recipe.keywords.add( Keyword.objects.get_or_create( space=self.request.space, name=x)[0]) except Exception: pass ingredients_added = False for s in recipe_json['recipeInstructions']: step = Step.objects.create( instruction=s, space=self.request.space, ) if not ingredients_added: if len(recipe_json['description'].strip()) > 500: step.instruction = recipe_json['description'].strip( ) + '\n\n' + step.instruction ingredients_added = True ingredient_parser = IngredientParser(self.request, True) for ingredient in recipe_json['recipeIngredient']: amount, unit, food, note = ingredient_parser.parse( ingredient) f = ingredient_parser.get_food(food) u = ingredient_parser.get_unit(unit) step.ingredients.add( Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space, )) recipe.steps.add(step) if 'nutrition' in recipe_json: try: recipe.nutrition.calories = recipe_json['nutrition'][ 'calories'].replace(' kcal', '').replace(' ', '') recipe.nutrition.proteins = recipe_json['nutrition'][ 'calories'].replace(' g', '').replace(',', '.').replace(' ', '') recipe.nutrition.fats = recipe_json['nutrition'][ 'calories'].replace(' g', '').replace(',', '.').replace(' ', '') recipe.nutrition.carbohydrates = recipe_json['nutrition'][ 'calories'].replace(' g', '').replace(',', '.').replace(' ', '') except Exception: pass for f in self.files: if '.zip' in f['name']: import_zip = ZipFile(f['file']) for z in import_zip.filelist: if re.match(f'^(.)+{recipe.name}/full.jpg$', z.filename): self.import_recipe_image( recipe, BytesIO(import_zip.read(z.filename)), filetype=get_filetype(z.filename)) return recipe
def get_recipe_from_file(self, file): ingredient_mode = False direction_mode = False ingredients = [] directions = [] for fl in file.readlines(): line = fl.decode("utf-8") if 'Title:' in line: title = line.replace('Title:', '').strip() if 'Description:' in line: description = line.replace('Description:', '').strip() if 'Yield:' in line: directions.append( _('Servings') + ' ' + line.replace('Yield:', '').strip() + '\n') if 'Cook:' in line: directions.append( _('Waiting time') + ' ' + line.replace('Cook:', '').strip() + '\n') if 'Prep:' in line: directions.append( _('Preparation Time') + ' ' + line.replace('Prep:', '').strip() + '\n') if 'Cookbook:' in line: directions.append( _('Cookbook') + ' ' + line.replace('Cookbook:', '').strip() + '\n') if 'Section:' in line: directions.append( _('Section') + ' ' + line.replace('Section:', '').strip() + '\n') if ingredient_mode: if len(line) > 2 and 'Instructions:' not in line: ingredients.append(line.strip()) if direction_mode: if len(line) > 2: directions.append(line.strip()) if 'Ingredients:' in line: ingredient_mode = True if 'Instructions:' in line: ingredient_mode = False direction_mode = True recipe = Recipe.objects.create( name=title, description=description, created_by=self.request.user, internal=True, space=self.request.space, ) step = Step.objects.create( instruction='\n'.join(directions), space=self.request.space, ) ingredient_parser = IngredientParser(self.request, True) for ingredient in ingredients: amount, unit, ingredient, note = ingredient_parser.parse( ingredient) f = ingredient_parser.get_food(ingredient) u = ingredient_parser.get_unit(unit) step.ingredients.add( Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, space=self.request.space, )) recipe.steps.add(step) return recipe
def get_recipe_from_file(self, file): # 'file' comes is as a beautifulsoup object recipe = Recipe.objects.create(name=file.find("div", {"id": "name"}).text.strip(), created_by=self.request.user, internal=True, space=self.request.space, ) for category in file.find_all("span", {"class": "recipeCategory"}): keyword, created = Keyword.objects.get_or_create(name=category.text, space=self.request.space) recipe.keywords.add(keyword) try: recipe.servings = parse_servings(file.find("a", {"id": "recipeYield"}).text.strip()) recipe.working_time = iso_duration_to_minutes(file.find("span", {"meta": "prepTime"}).text.strip()) recipe.waiting_time = iso_duration_to_minutes(file.find("span", {"meta": "cookTime"}).text.strip()) recipe.description = (file.find("div ", {"id": "description"}).text.strip())[:512] except AttributeError: pass try: if len(file.find("span", {"id": "starred"}).text.strip()) > 0: recipe.keywords.add(Keyword.objects.get_or_create(space=self.request.space, name=_('Favorite'))[0]) except AttributeError: pass step = Step.objects.create(instruction='', space=self.request.space, ) ingredient_parser = IngredientParser(self.request, True) for ingredient in file.find_all("li", {"class": "recipeIngredient"}): if ingredient.text == "": continue amount, unit, food, note = ingredient_parser.parse(ingredient.text.strip()) f = ingredient_parser.get_food(food) u = ingredient_parser.get_unit(unit) step.ingredients.add(Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, original_text=ingredient.text.strip(), space=self.request.space, )) for s in file.find_all("li", {"class": "instruction"}): if s.text == "": continue step.instruction += s.text.strip() + ' \n\n' for s in file.find_all("li", {"class": "recipeNote"}): if s.text == "": continue step.instruction += s.text.strip() + ' \n\n' try: if file.find("a", {"id": "original_link"}).text != '': step.instruction += "\n\n" + _("Imported from") + ": " + file.find("a", {"id": "original_link"}).text step.save() except AttributeError: pass recipe.steps.add(step) # import the Primary recipe image that is stored in the Zip try: for f in self.files: if '.zip' in f['name']: import_zip = ZipFile(f['file']) self.import_recipe_image(recipe, BytesIO(import_zip.read(file.find("img", class_="recipeImage").get("src"))), filetype='.jpeg') except Exception as e: print(recipe.name, ': failed to import image ', str(e)) recipe.save() return recipe
def get_recipe_from_file(self, file): recipe_json = file recipe = Recipe.objects.create(name=recipe_json['title'].strip(), created_by=self.request.user, internal=True, space=self.request.space) if 'yield' in recipe_json: recipe.servings = parse_servings(recipe_json['yield']) if 'cookTime' in recipe_json: recipe.waiting_time = parse_time(recipe_json['cookTime']) if 'prepTime' in recipe_json: recipe.working_time = parse_time(recipe_json['prepTime']) if 'favorite' in recipe_json and recipe_json['favorite']: recipe.keywords.add( Keyword.objects.get_or_create(space=self.request.space, name=_('Favorite'))[0]) if 'categories' in recipe_json: try: for x in recipe_json['categories']: recipe.keywords.add( Keyword.objects.get_or_create(space=self.request.space, name=x)[0]) except Exception: pass instruction = '' if 'text' in recipe_json: instruction += f'*{recipe_json["text"].strip()}* \n' if 'instructions' in recipe_json: instruction += recipe_json["instructions"].strip() + ' \n' if 'notes' in recipe_json: instruction += recipe_json["notes"].strip() + ' \n' if 'link' in recipe_json: recipe.source_url = recipe_json['link'] step = Step.objects.create( instruction=instruction, space=self.request.space, ) ingredient_parser = IngredientParser(self.request, True) for ingredient in recipe_json['ingredients'].split('\n'): if ingredient.strip() != '': amount, unit, food, note = ingredient_parser.parse(ingredient) f = ingredient_parser.get_food(food) u = ingredient_parser.get_unit(unit) step.ingredients.add( Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space, )) recipe.steps.add(step) if recipe_json.get("images", None): try: self.import_recipe_image( recipe, BytesIO(base64.b64decode(recipe_json['images'][0])), filetype='.jpeg') except Exception: pass return recipe
def get_recipe_from_file(self, file): recipe_xml = file recipe = Recipe.objects.create( name=recipe_xml.find('title').text.strip(), created_by=self.request.user, internal=True, space=self.request.space) if recipe_xml.find('preptime') is not None: recipe.working_time = parse_time( recipe_xml.find('preptime').text.strip()) if recipe_xml.find('cooktime') is not None: recipe.waiting_time = parse_time( recipe_xml.find('cooktime').text.strip()) if recipe_xml.find('quantity') is not None: recipe.servings = parse_servings( recipe_xml.find('quantity').text.strip()) recipe.servings_text = parse_servings_text( recipe_xml.find('quantity').text.strip()) if recipe_xml.find('url') is not None: recipe.source_url = recipe_xml.find('url').text.strip() if recipe_xml.find( 'description' ) is not None: # description is a list of <li>'s with text if len(recipe_xml.find('description')) > 0: recipe.description = recipe_xml.find( 'description')[0].text[:512] for step in recipe_xml.find('recipetext').getchildren(): step = Step.objects.create( instruction=step.text.strip(), space=self.request.space, ) recipe.steps.add(step) ingredient_parser = IngredientParser(self.request, True) for ingredient in recipe_xml.find('ingredient').getchildren(): if ingredient.text.strip() != '': amount, unit, food, note = ingredient_parser.parse( ingredient.text.strip()) f = ingredient_parser.get_food(food) u = ingredient_parser.get_unit(unit) recipe.steps.first().ingredients.add( Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, original_text=ingredient.text.strip(), space=self.request.space, )) if recipe_xml.find('imageurl') is not None: try: response = requests.get( recipe_xml.find('imageurl').text.strip()) self.import_recipe_image(recipe, BytesIO(response.content)) except Exception as e: print('failed to import image ', str(e)) recipe.save() return recipe
def get_recipe_from_file(self, file): ingredient_mode = False direction_mode = False description_mode = False ingredients = [] directions = [] descriptions = [] for fl in file.readlines(): line = fl.decode("utf-8") if 'title:' in line: title = line.replace('title:', '').replace('"', '').strip() if 'image:' in line: image = line.replace('image:', '').strip() if 'tags:' in line: tags = line.replace('tags:', '').strip() if ingredient_mode: if len(line) > 2 and 'directions:' not in line: ingredients.append(line[2:]) if '---' in line and direction_mode: direction_mode = False description_mode = True if direction_mode: if len(line) > 2: directions.append(line[2:]) if 'ingredients:' in line: ingredient_mode = True if 'directions:' in line: ingredient_mode = False direction_mode = True if description_mode and len(line) > 3 and '---' not in line: descriptions.append(line) recipe = Recipe.objects.create(name=title, created_by=self.request.user, internal=True, space=self.request.space) for k in tags.split(','): print(f'adding keyword {k.strip()}') keyword, created = Keyword.objects.get_or_create(name=k.strip(), space=self.request.space) recipe.keywords.add(keyword) step = Step.objects.create( instruction='\n'.join(directions) + '\n\n' + '\n'.join(descriptions), space=self.request.space, ) ingredient_parser = IngredientParser(self.request, True) for ingredient in ingredients: amount, unit, ingredient, note = ingredient_parser.parse(ingredient) f = ingredient_parser.get_food(ingredient) u = ingredient_parser.get_unit(unit) step.ingredients.add(Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, space=self.request.space, )) recipe.steps.add(step) for f in self.files: if '.zip' in f['name']: import_zip = ZipFile(f['file']) for z in import_zip.filelist: if re.match(f'^images/{image}$', z.filename): self.import_recipe_image(recipe, BytesIO(import_zip.read(z.filename)), filetype=get_filetype(z.filename)) return recipe
def import_url(request): if request.space.max_recipes != 0 and Recipe.objects.filter( space=request.space ).count( ) >= request.space.max_recipes: # TODO move to central helper function messages.add_message( request, messages.WARNING, _('You have reached the maximum number of recipes for your space.') ) return HttpResponseRedirect(reverse('index')) if request.space.max_users != 0 and UserPreference.objects.filter( space=request.space).count() > request.space.max_users: messages.add_message( request, messages.WARNING, _('You have more users than allowed in your space.')) return HttpResponseRedirect(reverse('index')) if request.method == 'POST': data = json.loads(request.body) data['cookTime'] = parse_cooktime(data.get('cookTime', '')) data['prepTime'] = parse_cooktime(data.get('prepTime', '')) recipe = Recipe.objects.create( name=data['name'], description=data['description'], waiting_time=data['cookTime'], working_time=data['prepTime'], servings=data['servings'], internal=True, created_by=request.user, space=request.space, ) step = Step.objects.create( instruction=data['recipeInstructions'], space=request.space, ) recipe.steps.add(step) for kw in data['keywords']: if data['all_keywords']: # do not remove this check :) https://github.com/vabene1111/recipes/issues/645 k, created = Keyword.objects.get_or_create(name=kw['text'], space=request.space) recipe.keywords.add(k) else: try: k = Keyword.objects.get(name=kw['text'], space=request.space) recipe.keywords.add(k) except ObjectDoesNotExist: pass ingredient_parser = IngredientParser(request, True) for ing in data['recipeIngredient']: ingredient = Ingredient(space=request.space, ) if food_text := ing['ingredient']['text'].strip(): ingredient.food = ingredient_parser.get_food(food_text) if ing['unit']: if unit_text := ing['unit']['text'].strip(): ingredient.unit = ingredient_parser.get_unit(unit_text) # TODO properly handle no_amount recipes if isinstance(ing['amount'], str): try: ingredient.amount = float(ing['amount'].replace(',', '.')) except ValueError: ingredient.no_amount = True pass elif isinstance(ing['amount'], float) \ or isinstance(ing['amount'], int): ingredient.amount = ing['amount'] ingredient.note = ing['note'].strip() if 'note' in ing else '' ingredient.save() step.ingredients.add(ingredient)
def get_recipe_from_file(self, file): with gzip.open(file, 'r') as recipe_zip: recipe_json = json.loads(recipe_zip.read().decode("utf-8")) recipe = Recipe.objects.create(name=recipe_json['name'].strip(), created_by=self.request.user, internal=True, space=self.request.space) if 'description' in recipe_json: recipe.description = '' if len( recipe_json['description'].strip( )) > 500 else recipe_json['description'].strip() try: if 'servings' in recipe_json['servings']: recipe.servings = parse_servings(recipe_json['servings']) recipe.servings_text = parse_servings_text( recipe_json['servings']) if len(recipe_json['cook_time'].strip()) > 0: recipe.waiting_time = re.findall( r'\d+', recipe_json['cook_time'])[0] if len(recipe_json['prep_time'].strip()) > 0: recipe.working_time = re.findall( r'\d+', recipe_json['prep_time'])[0] except Exception: pass recipe.save() instructions = recipe_json['directions'] if recipe_json['notes'] and len(recipe_json['notes'].strip()) > 0: instructions += '\n\n### ' + _( 'Notes') + ' \n' + recipe_json['notes'] if recipe_json['nutritional_info'] and len( recipe_json['nutritional_info'].strip()) > 0: instructions += '\n\n### ' + _( 'Nutritional Information' ) + ' \n' + recipe_json['nutritional_info'] try: if len(recipe_json['source'].strip()) > 0 or len( recipe_json['source_url'].strip()) > 0: instructions += '\n\n### ' + _( 'Source') + ' \n' + recipe_json['source'].strip( ) + ' \n' + recipe_json['source_url'].strip() except AttributeError: pass step = Step.objects.create( instruction=instructions, space=self.request.space, ) if 'description' in recipe_json and len( recipe_json['description'].strip()) > 500: step.instruction = recipe_json['description'].strip( ) + '\n\n' + step.instruction if 'categories' in recipe_json: for c in recipe_json['categories']: keyword, created = Keyword.objects.get_or_create( name=c.strip(), space=self.request.space) recipe.keywords.add(keyword) ingredient_parser = IngredientParser(self.request, True) try: for ingredient in recipe_json['ingredients'].split('\n'): if len(ingredient.strip()) > 0: amount, unit, food, note = ingredient_parser.parse( ingredient) f = ingredient_parser.get_food(food) u = ingredient_parser.get_unit(unit) step.ingredients.add( Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space, )) except AttributeError: pass recipe.steps.add(step) if recipe_json.get("photo_data", None): self.import_recipe_image( recipe, BytesIO(base64.b64decode(recipe_json['photo_data'])), filetype='.jpeg') return recipe
def get_recipe_from_file(self, file): # Create initial recipe with just a title and a description recipe = Recipe.objects.create( name=file['title'], created_by=self.request.user, internal=True, space=self.request.space, ) # set the description as an empty string for later use for the source URL, in case there is no description text. recipe.description = '' try: if file['description'] != '': recipe.description = file['description'].strip() except Exception as e: print(recipe.name, ': failed to parse recipe description ', str(e)) instructions = file['instructions'] if not instructions: instructions = '' step = Step.objects.create( instruction=instructions, space=self.request.space, ) # Append the original import url to the step (if it exists) try: if file['url'] != '': step.instruction += '\n\n' + _( 'Imported from') + ': ' + file['url'] step.save() except Exception as e: print(recipe.name, ': failed to import source url ', str(e)) try: # Process the ingredients. Assumes 1 ingredient per line. ingredient_parser = IngredientParser(self.request, True) for ingredient in file['ingredients'].split('\n'): if len(ingredient.strip()) > 0: amount, unit, food, note = ingredient_parser.parse(food) f = ingredient_parser.get_food(ingredient) u = ingredient_parser.get_unit(unit) step.ingredients.add( Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, original_text=ingredient, space=self.request.space, )) except Exception as e: print(recipe.name, ': failed to parse recipe ingredients ', str(e)) recipe.steps.add(step) # Attempt to import prep/cooking times # quick hack, this assumes only one number in the quantity field. try: if file['quantity'] != '': for item in file['quantity'].split(' '): if item.isdigit(): recipe.servings = int(item) break except Exception as e: print(recipe.name, ': failed to parse quantity ', str(e)) try: if file['totalTime'] != '': recipe.waiting_time = int(file['totalTime']) except Exception as e: print(recipe.name, ': failed to parse total times ', str(e)) try: if file['preparationTime'] != '': recipe.working_time = int(file['preparationTime']) except Exception as e: print(recipe.name, ': failed to parse prep time ', str(e)) try: if file['cookingTime'] != '': recipe.waiting_time = int(file['cookingTime']) except Exception as e: print(recipe.name, ': failed to parse cooking time ', str(e)) recipe.save() # Import the recipe keywords try: if file['keywords'] != '': for keyword in file['keywords'].split(';'): k, created = Keyword.objects.get_or_create( name=keyword.strip(), space=self.request.space) recipe.keywords.add(k) recipe.save() except Exception as e: print(recipe.name, ': failed to parse keywords ', str(e)) # TODO: Parse Nutritional Information # Import the original image from the zip file, if we cannot do that, attempt to download it again. try: if file['pictures'][0] != '': image_file_name = file['pictures'][0].split('/')[-1] for f in self.files: if '.rtk' in f['name']: import_zip = ZipFile(f['file']) self.import_recipe_image( recipe, BytesIO(import_zip.read(image_file_name)), filetype=get_filetype(image_file_name)) else: if file['originalPicture'] != '': response = requests.get(file['originalPicture']) if imghdr.what(BytesIO(response.content)) is not None: self.import_recipe_image(recipe, BytesIO(response.content), filetype=get_filetype( file['originalPicture'])) else: raise Exception("Original image failed to download.") except Exception as e: print(recipe.name, ': failed to import image ', str(e)) return recipe
def get_recipe_from_file(self, file): ingredient_mode = False direction_mode = False image_url = None tags = None ingredients = [] directions = [] description = '' for line in file.replace('\r', '').split('\n'): if line.strip() != '': if 'Title:' in line: title = line.replace('Title:', '').replace('"', '').strip() if 'Description:' in line: description = line.replace('Description:', '').strip() if 'Source:' in line or 'Serves:' in line or 'Prep Time:' in line or 'Cook Time:' in line: directions.append(line.strip() + '\n') if 'Photo Url:' in line: image_url = line.replace('Photo Url:', '').strip() if 'Tags:' in line: tags = line.replace('Tags:', '').strip() if ingredient_mode: if len(line) > 2 and 'Instructions:' not in line: ingredients.append(line.strip()) if direction_mode: if len(line) > 2: directions.append(line.strip() + '\n') if 'Ingredients:' in line: ingredient_mode = True if 'Directions:' in line: ingredient_mode = False direction_mode = True recipe = Recipe.objects.create(name=title, description=description, created_by=self.request.user, internal=True, space=self.request.space) step = Step.objects.create( instruction='\n'.join(directions) + '\n\n', space=self.request.space, ) if tags: for k in tags.split(','): keyword, created = Keyword.objects.get_or_create( name=k.strip(), space=self.request.space) recipe.keywords.add(keyword) ingredient_parser = IngredientParser(self.request, True) for ingredient in ingredients: if len(ingredient.strip()) > 0: amount, unit, ingredient, note = ingredient_parser.parse( ingredient) f = ingredient_parser.get_food(ingredient) u = ingredient_parser.get_unit(unit) step.ingredients.add( Ingredient.objects.create( food=f, unit=u, amount=amount, note=note, space=self.request.space, )) recipe.steps.add(step) if image_url: try: response = requests.get(image_url) self.import_recipe_image(recipe, BytesIO(response.content)) except Exception as e: print('failed to import image ', str(e)) return recipe