feat(api): 增加从下厨房复制菜谱的功能
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
d03190e810
commit
9787a6230d
60
app.py
60
app.py
@ -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
20
recipe.py
Normal 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}
|
||||
Loading…
x
Reference in New Issue
Block a user