上傳檔案到「/」
-- 指定專案資料夾 cd /employee_votes -- gitea 初始化 git init -- 建立註解 git add . git commit -m "Initial commit" -- 切換到 main 分支 git branch -M main -- 上傳檔案到 gitea git remote add origin https://github.com/91771/<REPO>.git git push -u origin main
This commit is contained in:
304
app_backup.py
Normal file
304
app_backup.py
Normal file
@@ -0,0 +1,304 @@
|
||||
from flask import Flask, render_template, request, jsonify
|
||||
import mysql.connector
|
||||
import requests
|
||||
from bs4 import BeautifulSoup
|
||||
import json
|
||||
from datetime import datetime
|
||||
import re
|
||||
import urllib3
|
||||
|
||||
# 禁用SSL警告
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# Database configuration from DB_connection.txt
|
||||
DB_CONFIG = {
|
||||
'host': 'mysql.theaken.com',
|
||||
'port': 33306,
|
||||
'database': 'db_A019',
|
||||
'user': 'A019',
|
||||
'password': '9wvKEkxBzVca'
|
||||
}
|
||||
|
||||
def get_db_connection():
|
||||
"""Establish database connection"""
|
||||
try:
|
||||
conn = mysql.connector.connect(**DB_CONFIG)
|
||||
return conn
|
||||
except mysql.connector.Error as e:
|
||||
print(f"Database connection error: {e}")
|
||||
return None
|
||||
|
||||
def create_menu_table():
|
||||
"""Create menu_items table if not exists"""
|
||||
conn = get_db_connection()
|
||||
if conn:
|
||||
try:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS menu_items (
|
||||
Id INTEGER AUTO_INCREMENT PRIMARY KEY,
|
||||
main_course VARCHAR(50) NOT NULL,
|
||||
side_dish VARCHAR(50),
|
||||
addon VARCHAR(50),
|
||||
is_active BOOLEAN NOT NULL
|
||||
)
|
||||
""")
|
||||
conn.commit()
|
||||
print("Menu table created or already exists")
|
||||
except mysql.connector.Error as e:
|
||||
print(f"Error creating table: {e}")
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
def scrape_menu_data():
|
||||
"""Scrape menu data from the target URL"""
|
||||
url = "https://club.panjit.com.tw/back/menu/menu.php?1672970133&indexselectid=1"
|
||||
|
||||
try:
|
||||
# Bypass SSL verification for the target website
|
||||
response = requests.get(url, timeout=10, verify=False)
|
||||
response.raise_for_status()
|
||||
|
||||
soup = BeautifulSoup(response.content, 'html.parser')
|
||||
|
||||
# 根據實際網站結構解析菜單資料
|
||||
menu_items = []
|
||||
|
||||
# 查找菜單表格或列表
|
||||
menu_tables = soup.find_all('table')
|
||||
menu_lists = soup.find_all(['ul', 'ol'])
|
||||
|
||||
# 如果找到表格結構
|
||||
if menu_tables:
|
||||
for table in menu_tables:
|
||||
rows = table.find_all('tr')
|
||||
for row in rows:
|
||||
cells = row.find_all('td')
|
||||
if len(cells) >= 2: # 至少有名稱和價格
|
||||
name = cells[0].get_text(strip=True)
|
||||
price_text = cells[1].get_text(strip=True)
|
||||
|
||||
# 提取價格數字
|
||||
price = 0.0
|
||||
try:
|
||||
# 從文字中提取數字
|
||||
price_match = re.search(r'\d+', price_text)
|
||||
if price_match:
|
||||
price = float(price_match.group())
|
||||
except:
|
||||
pass
|
||||
|
||||
if name and price > 0:
|
||||
menu_items.append({
|
||||
'name': name,
|
||||
'category': '主餐',
|
||||
'price': price,
|
||||
'description': f'{name} - 美味餐點',
|
||||
'image_url': f'/static/images/{name.replace(" ", "_").lower()}.jpg'
|
||||
})
|
||||
|
||||
# 如果找到列表結構
|
||||
elif menu_lists:
|
||||
for menu_list in menu_lists:
|
||||
items = menu_list.find_all('li')
|
||||
for item in items:
|
||||
text = item.get_text(strip=True)
|
||||
if text and any(char.isdigit() for char in text):
|
||||
# 嘗試解析項目名稱和價格
|
||||
# 尋找價格模式
|
||||
price_match = re.search(r'(\$|NT\$|\$)?\s*(\d+)', text)
|
||||
if price_match:
|
||||
price = float(price_match.group(2))
|
||||
name = re.sub(r'(\$|NT\$|\$)?\s*\d+', '', text).strip()
|
||||
|
||||
if name and price > 0:
|
||||
menu_items.append({
|
||||
'name': name,
|
||||
'category': '餐點',
|
||||
'price': price,
|
||||
'description': f'{name} - 精選美食',
|
||||
'image_url': f'/static/images/{name.replace(" ", "_").lower()}.jpg'
|
||||
})
|
||||
|
||||
# 如果以上方法都沒找到,使用備用方案:搜尋包含菜單文字的div或span
|
||||
if not menu_items:
|
||||
# 尋找可能包含菜單項目的元素
|
||||
possible_menu_elements = soup.find_all(['div', 'span', 'p'])
|
||||
for elem in possible_menu_elements:
|
||||
text = elem.get_text(strip=True)
|
||||
if text and len(text) > 3 and any(char.isdigit() for char in text):
|
||||
price_match = re.search(r'(\$|NT\$|\$)?\s*(\d+)', text)
|
||||
if price_match:
|
||||
price = float(price_match.group(2))
|
||||
name = re.sub(r'(\$|NT\$|\$)?\s*\d+.*', '', text).strip()
|
||||
|
||||
if name and price > 0 and len(name) > 1:
|
||||
menu_items.append({
|
||||
'name': name,
|
||||
'category': '餐點',
|
||||
'price': price,
|
||||
'description': f'{name} - 餐廳推薦',
|
||||
'image_url': f'/static/images/{name.replace(" ", "_").lower()}.jpg'
|
||||
})
|
||||
|
||||
# 如果仍然沒有找到菜單項目,使用範例資料
|
||||
if not menu_items:
|
||||
menu_items = [
|
||||
{
|
||||
'name': '經典牛肉麵',
|
||||
'category': '主食',
|
||||
'price': 120.00,
|
||||
'description': '傳統台灣牛肉麵,湯頭濃郁',
|
||||
'image_url': '/static/images/beef_noodle.jpg'
|
||||
},
|
||||
{
|
||||
'name': '雞腿飯',
|
||||
'category': '主食',
|
||||
'price': 95.00,
|
||||
'description': '香煎雞腿配時蔬',
|
||||
'image_url': '/static/images/chicken_rice.jpg'
|
||||
},
|
||||
{
|
||||
'name': '蔬菜沙拉',
|
||||
'category': '前菜',
|
||||
'price': 65.00,
|
||||
'description': '新鮮時蔬搭配特製醬料',
|
||||
'image_url': '/static/images/salad.jpg'
|
||||
},
|
||||
{
|
||||
'name': '紅燒獅子頭',
|
||||
'category': '主餐',
|
||||
'price': 150.00,
|
||||
'description': '傳統江浙菜,肉質鮮嫩',
|
||||
'image_url': '/static/images/lion_head.jpg'
|
||||
},
|
||||
{
|
||||
'name': '炒青菜',
|
||||
'category': '蔬菜',
|
||||
'price': 60.00,
|
||||
'description': '時令蔬菜清炒',
|
||||
'image_url': '/static/images/vegetable.jpg'
|
||||
}
|
||||
]
|
||||
|
||||
return menu_items
|
||||
|
||||
except requests.RequestException as e:
|
||||
print(f"Error scraping menu data: {e}")
|
||||
# 返回範例資料作為備用
|
||||
return [
|
||||
{
|
||||
'name': '經典牛肉麵',
|
||||
'category': '主食',
|
||||
'price': 120.00,
|
||||
'description': '傳統台灣牛肉麵,湯頭濃郁',
|
||||
'image_url': '/static/images/beef_noodle.jpg'
|
||||
},
|
||||
{
|
||||
'name': '雞腿飯',
|
||||
'category': '主食',
|
||||
'price': 95.00,
|
||||
'description': '香煎雞腿配時蔬',
|
||||
'image_url': '/static/images/chicken_rice.jpg'
|
||||
}
|
||||
]
|
||||
|
||||
def insert_menu_data():
|
||||
"""Insert sample menu items into database"""
|
||||
conn = get_db_connection()
|
||||
if conn:
|
||||
try:
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Clear existing data
|
||||
cursor.execute("DELETE FROM menu_items")
|
||||
|
||||
# Insert sample data that matches the new table structure
|
||||
sample_menu_items = [
|
||||
('經典牛肉麵', '手工麵條', '酸菜湯', True),
|
||||
('香煎雞腿飯', '時令蔬菜', '玉米濃湯', True),
|
||||
('紅燒獅子頭', '白飯', '紫菜蛋花湯', True),
|
||||
('蔬菜炒麵', None, '味噌湯', True),
|
||||
('烤鮭魚排', '馬鈴薯泥', '南瓜湯', True)
|
||||
]
|
||||
|
||||
insert_query = """
|
||||
INSERT INTO menu_items (main_course, side_dish, addon, is_active)
|
||||
VALUES (%s, %s, %s, %s)
|
||||
"""
|
||||
|
||||
for item in sample_menu_items:
|
||||
cursor.execute(insert_query, item)
|
||||
|
||||
conn.commit()
|
||||
print(f"Inserted {len(sample_menu_items)} menu items")
|
||||
|
||||
except mysql.connector.Error as e:
|
||||
print(f"Error inserting menu data: {e}")
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
@app.route('/')
|
||||
def index():
|
||||
"""Main page - display menu items"""
|
||||
conn = get_db_connection()
|
||||
menu_items = []
|
||||
|
||||
if conn:
|
||||
try:
|
||||
cursor = conn.cursor(dictionary=True)
|
||||
cursor.execute("SELECT * FROM menu_items ORDER BY category, name")
|
||||
menu_items = cursor.fetchall()
|
||||
except mysql.connector.Error as e:
|
||||
print(f"Error fetching menu items: {e}")
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
return render_template('index.html', menu_items=menu_items)
|
||||
|
||||
@app.route('/api/menu')
|
||||
def api_menu():
|
||||
"""API endpoint to get menu items"""
|
||||
conn = get_db_connection()
|
||||
menu_items = []
|
||||
|
||||
if conn:
|
||||
try:
|
||||
cursor = conn.cursor(dictionary=True)
|
||||
cursor.execute("SELECT * FROM menu_items ORDER BY category, name")
|
||||
menu_items = cursor.fetchall()
|
||||
except mysql.connector.Error as e:
|
||||
print(f"Error fetching menu items: {e}")
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
return jsonify(menu_items)
|
||||
|
||||
@app.route('/init')
|
||||
def initialize():
|
||||
"""Initialize database with menu data"""
|
||||
create_menu_table()
|
||||
insert_menu_data()
|
||||
return "Database initialized with sample menu data"
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Initialize database on startup
|
||||
create_menu_table()
|
||||
|
||||
# Check if menu items exist, if not, insert sample data
|
||||
conn = get_db_connection()
|
||||
if conn:
|
||||
try:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT COUNT(*) FROM menu_items")
|
||||
count = cursor.fetchone()[0]
|
||||
if count == 0:
|
||||
insert_menu_data()
|
||||
except mysql.connector.Error as e:
|
||||
print(f"Error checking menu items: {e}")
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
app.run(debug=True, port=5000)
|
Reference in New Issue
Block a user