feat(api): 增加从下厨房复制菜谱的功能
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Ching 2024-03-04 01:56:10 +08:00
parent d03190e810
commit 9787a6230d
2 changed files with 80 additions and 0 deletions

60
app.py
View File

@ -1,12 +1,15 @@
# coding = utf-8
import json
import os
import re
import requests
from flask import Flask, jsonify, request
from pygrocy import EntityType, Grocy
from barcode import BarcodeSpider
from recipe import get_recipe_from_xiachufang
import base64
# config = configparser.ConfigParser()
# config.read('config.ini')
@ -174,6 +177,11 @@ def gpc_best_before_days(Code):
return day
def convert_image_to_base64(image_content):
base64_image = base64.b64encode(image_content).decode("utf-8")
return base64_image
@app.route("/")
def index():
return "Up and running!"
@ -225,5 +233,57 @@ def consume():
return jsonify(response_data), 400
@app.route("/add_recipe", methods=["POST"])
def add_recipe():
data = request.json
source = data.get("source", "xiachufang")
url = data.get("url", "")
if source != "xiachufang":
response_data = {"message": "Invalid source"}
return jsonify(response_data), 400
if not url:
response_data = {"message": "Invalid url"}
return jsonify(response_data), 400
try:
# https://www.xiachufang.com/recipe/107141278/?recipe_type=1&page_scene=6
recipe_number = re.search(r'(\d+)', url).group(1)
resp = grocy.get_generic_objects_for_type(EntityType.RECIPES, ['name~%s' % recipe_number])
if resp:
response_data = {"message": "Recipe already exists"}
return jsonify(response_data), 400
xcf_recipe = get_recipe_from_xiachufang(url)
description = ""
if xcf_recipe['ingredients']:
description += "<h2>用料</h2>\n"
description += "<ul>\n"
for ingredient in xcf_recipe["ingredients"]:
description += f'<li>{ingredient}</li>\n'
description += "</ul>\n"
if xcf_recipe['steps']:
description += "<h2>做法</h2>\n"
for idx, step in enumerate(xcf_recipe["steps"]):
description += f"<h3>步骤 {idx+1}</h3>\n"
description += f'<p>{step[0]}</p>\n'
if len(step) == 1:
description += "<br>"
continue
img = requests.get(step[1])
img_data = 'data:image/png;base64,' + convert_image_to_base64(img.content)
description += f'\n<img src=\"{img_data}\">\n\n'
description += "<br>"
data_grocy = {
"name": xcf_recipe["name"] + " - " + recipe_number,
"description": description
}
grocy.add_generic(EntityType.RECIPES, data_grocy)
response_data = {"message": "Recipe added successfully"}
except Exception as e:
error_message = str(e)
response_data = {"message": error_message}
return jsonify(response_data), 400
return jsonify(response_data), 200
if __name__ == "__main__":
app.run(host="0.0.0.0", port=9288)

20
recipe.py Normal file
View File

@ -0,0 +1,20 @@
import requests
import bs4
ua = 'Mozilla/5.0.html (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.html.2171.71 Safari/537.36'
def get_recipe_from_xiachufang(url):
headers = {'User-Agent': ua}
response = requests.get(url, headers=headers)
response.raise_for_status()
soup = bs4.BeautifulSoup(response.text, 'html.parser')
name = soup.find('h1', class_='page-title').text.strip()
ingredients = []
for ingredient in soup.find('div', class_='ings').find('table').find_all('tr'):
ingredients.append(' / '.join([td.text.strip() for td in ingredient.find_all('td')]))
steps = []
for step in soup.find('div', class_='steps').find('ol').find_all('li'):
steps.append([step.find('p').text.strip(), step.find('img')['src']])
return {'name': name, 'ingredients': ingredients, 'steps': steps}