def view(attractionId): '''restful-api, select single data using id.''' if request.method == "GET": try: db = DB_controller( host=DB_HOST, user=DB_USER, password=DB_PWD, db=DB_NAME ) result = db.show_data("attractions", "id", attractionId) db.close() if not result: return jsonify({"data": None}) data = { "data": { "id": result[0], "name": result[1], "category": result[2], "description": result[3], "address": result[4], "transport": result[5], "mrt": result[6], "latitude": str(result[7]), "longitude": str(result[8]), "images": result[9], } } res = make_response(jsonify(data)) return res except Exception as e: return jsonify({"error": True, "message": str(e)}), 500
def order_list(): if request.method == "GET": if not session.get("email"): return jsonify({"error":True, "message":"尚未登入會員"}), 403 clean_order_list = [] try: db = DB_controller( host=DB_HOST, user=DB_USER, password=DB_PWD, db=DB_NAME ) user_data = db.show_data("user", "email", session.get("email")) order_list = db.fetch_all_data("orders", "userId", user_data[0]) if not order_list: return jsonify({"data": None}) for one in order_list: time_format = one[10] time_format = time_format.strftime("%Y-%m-%d %H:%M:%S") one_data = { "number": one[1], "create_time": time_format, "order_price": one[8], "status": one[9] } clean_order_list.append(one_data) return jsonify({"data": clean_order_list}) except Exception as e: return jsonify({"error":True, "message": str(e)}), 500
def user_login(): '''user login process''' if request.method == "PATCH": login_data = request.get_json() # 這樣應該就會回傳sessionId到使用者Response Headers email = login_data["email"] pwd = login_data["password"] rex_email = r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)" # email格式 match = re.match(rex_email, email) if email == "": return jsonify({"error": True, "message": "不可為空值"}), 400 if not match: return jsonify({"error": True, "message": "請輸入正確email"}), 400 if pwd == "": return jsonify({"error": True, "message": "不可為空值"}), 400 try: db = DB_controller( host=DB_HOST, user=DB_USER, password=DB_PWD, db=DB_NAME ) data = db.show_data("user", "email", email) db.close() if data: if data[2] == email: # 帳號大小寫比對 hash_ = HASH hash_pwd = pwd + hash_ hash_pwd = hashlib.sha256(hash_pwd.encode("utf-8")).hexdigest() if hash_pwd == data[3]: session["email"] = email # 確認email&密碼輸入正確才會存session res = make_response(jsonify({"ok": True})) return res else: return jsonify({"error": True, "message": "帳號或密碼錯誤"}), 400 else: return jsonify({"error": True, "message": "帳號或密碼錯誤"}), 400 else: return jsonify({"error": True, "message": "此email尚未被註冊"}), 400 except Exception as e: return jsonify({"error": True, "message": str(e)}), 500
def tearDown(self): #失敗 無法刪除db裡的資料 db = DB_controller(host=DB_HOST, user=DB_USER, password=DB_PWD, db=DB_NAME) db.delete(table_name="user", column_name="name", value=self.name) db.close()
def user_register(): '''new user register process''' if request.method == "POST": post_data = request.get_json() # 登入才要給一個sessionId name = post_data["name"] email = post_data["email"] pwd = post_data["password"] rex_email = r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)" # email格式 match = re.match(rex_email, email) if name == "": return jsonify({"error": True, "message": "不可為空值"}), 400 if email == "": return jsonify({"error": True, "message": "不可為空值"}), 400 if not match: return jsonify({"error": True, "message": "請輸入正確email"}), 400 if pwd == "": return jsonify({"error": True, "message": "不可為空值"}), 400 try: db = DB_controller( host=DB_HOST, user=DB_USER, password=DB_PWD, db=DB_NAME ) email_check = db.show_data("user", "email", email) name_check = db.show_data("user", "name", name) if not email_check: if not name_check: hash_ = HASH hash_pwd = pwd + hash_ hash_pwd = hashlib.sha256( hash_pwd.encode("utf-8")).hexdigest() db.insert_data("user", "name, email, password", f'"{name}","{email}","{hash_pwd}"') db.close() res = make_response(jsonify({"ok": True})) return res else: return jsonify({"error": True, "message": "此暱稱已被使用"}), 400 else: return jsonify({"error": True, "message": "此email已註冊過"}), 400 except Exception as e: return jsonify({"error": True, "message": str(e)}), 500
def get_logined_user(): '''logined user infomation''' if request.method == "GET": # 判斷有sessionId => 取得db裡的資料 => 回傳使用者資料 if session.get("email") is None: return jsonify({"data": None}) else: try: db = DB_controller( host=DB_HOST, user=DB_USER, password=DB_PWD, db=DB_NAME ) data = db.show_data("user", "email", session.get("email")) db.close() res = make_response(jsonify({"data": { "id": data[0], "name": data[1], "email": data[2] }})) return res except Exception as e: return jsonify({"error": True, "message": str(e)}), 500
def order_info(ordernumber): # 訂單資訊 if request.method == "GET": if not session.get("email"): return jsonify({"error": True, "message": "尚未登入系統"}), 403 try: db = DB_controller( host=DB_HOST, user=DB_USER, password=DB_PWD, db=DB_NAME ) order_data = db.show_data("orders", "order_number", ordernumber) if not order_data: return jsonify({"data": None}) user_data = db.show_data("user", "email", session.get("email")) attraction_data = db.show_data("attractions", "id", order_data[3]) db.close() images = attraction_data[9] image = selectOneImage(images) date_format = order_data[6].strftime("%Y-%m-%d") return_data = { "data": { "number": ordernumber, "bank_transaction": order_data[2], "price": order_data[8], "date": date_format, "time": order_data[7], "status": order_data[9], "trip": { "attraction": { "id": attraction_data[0], "name": attraction_data[1], "address": attraction_data[4], "image": image } }, "contact": { "name": user_data[1], "email": user_data[2], "phone": order_data[4] } } } return jsonify(return_data) except Exception as e: return jsonify({"error":True, "message": str(e)}), 500
def uncheck_booking(): '''user scheduled trip record''' # 搜尋userId,如果該id存在,表示按過開始預定行程 if request.method == "GET": user_email = session.get("email") if not user_email: return jsonify({"error": True, "message": "請先登入會員"}), 403 else: try: db = DB_controller(host=DB_HOST, user=DB_USER, password=DB_PWD, db=DB_NAME) user_data = db.show_data("user", "email", user_email) booking_data = db.show_data("booking", "userId", user_data[0]) #此使用人的booking資料 if booking_data is None: return jsonify({"data": None}) else: attraction_data = db.show_data("attractions", "id", booking_data[1]) images = attraction_data[9] image = selectOneImage(images) date = booking_data[3] date_format = date.strftime("%Y-%m-%d") data = { "data": { "attraction": { "id": attraction_data[0], "name": attraction_data[1], "address": attraction_data[4], "image": image }, "date": date_format, "time": booking_data[4], "price": booking_data[5] } } res = make_response(jsonify(data)) db.close() return res except Exception as e: return jsonify({"error": True, "message": str(e)}), 500
def delete_booking(): '''want to delete a scheduled''' if request.method == "DELETE": user_email = session.get("email") if not user_email: return jsonify({"error": True, "message": "請先登入會員"}), 403 try: db = DB_controller(host=DB_HOST, user=DB_USER, password=DB_PWD, db=DB_NAME) user_data = db.show_data("user", "email", user_email) # 查詢使用者 booking_data = db.show_data("booking", "userId", user_data[0]) #此使用人的booking資料 db.delete("booking", "bookingId", booking_data[0]) #刪除該資料 res = make_response(jsonify({"ok": True})) return res except Exception as e: return jsonify({"error": True, "message": str(e)}), 500
def build_order(): if request.method == "POST": post_data = request.get_json() if not session.get("email"): return jsonify({"error":True, "message": "未登入會員系統"}), 403 user_name = post_data["contact"]["name"] email = post_data["contact"]["email"] phone = post_data["contact"]["phone"] attractionId = post_data["order"]["trip"]["attraction"]["id"] date = post_data["order"]["date"] time = post_data["order"]["time"] price = post_data["order"]["price"] rex_email = r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$)" # email格式 rex_phone = r"\d\d\d\d\d\d\d\d\d\d" match_email = re.match(rex_email, email) match_phone = re.match(rex_phone, phone) if user_name == "": return jsonify({"error": True, "message": "不可為空值"}), 400 if email == "": return jsonify({"error": True, "message": "不可為空值"}), 400 if not match_email: return jsonify({"error": True, "message": "email格式錯誤"}), 400 if phone == "": return jsonify({"error": True, "message": "不可為空值"}), 400 if not match_phone: return jsonify({"error": True, "message": "手機號碼格式錯誤"}), 400 try: # 創建訂單編號 now = dt.today() order_number = now.strftime("%Y%m%d%H%M%S") order_status = -1 # 記錄訂單付款狀態 初始值設-1 0付款成功, 1付款失敗 try: #訂單資訊存到db db = DB_controller( host=DB_HOST, user=DB_USER, password=DB_PWD, db=DB_NAME ) user_data = db.show_data("user", "email", post_data["contact"]["email"]) userId = user_data[0] prev_order_data = db.show_data("orders", "userId", userId) #還沒有付款成功 => 不用存bank_transaction if not prev_order_data: # 沒有過訂單 db.insert_data(table_name='orders', settingrow='order_number, attractionId, userId, phone, date, time, price, status', settingvalue=f'"{order_number}","{attractionId}", "{userId}", "{phone}","{date}", "{time}", "{price}", "{order_status}"') elif prev_order_data[9] == 0: #成功付款過,直接新增新的資料 db.insert_data(table_name='orders', settingrow='order_number, attractionId, userId, phone, date, time, price, status', settingvalue=f'"{order_number}","{attractionId}", "{userId}", "{phone}","{date}", "{time}", "{price}", "{order_status}"') elif prev_order_data[9] == 1: #付款失敗過(紀錄留存),可直接新增資料 db.insert_data(table_name='orders', settingrow='order_number, attractionId, userId, phone, date, time, price, status', settingvalue=f'"{order_number}","{attractionId}", "{userId}", "{phone}","{date}", "{time}", "{price}", "{order_status}"') except Exception as e: return jsonify({"error": True, "message": str(e)}), 500 # 進行付款動作 # tayppay.Client(is_sanbox, partner_key, merchant_id) 這裡都用官方提供測試用 => 沙盒 (要使用自己的key,id需要真的創建公司並且通過審核) client = tappay.Client(True, PARTNER_KEY, MERCHANT_ID) card_holder_data = tappay.Models.CardHolderData(post_data["contact"]["phone"], post_data["contact"]["name"], post_data["contact"]["email"]) # client.pay_by_prime(prime, amount, details, card_holder_data) response_data_dict = client.pay_by_prime("test_3a2fb2b7e892b914a03c95dd4dd5dc7970c908df67a49527c0a648b2bc9", post_data["order"]["price"], post_data["order"]["trip"]["attraction"]["name"], card_holder_data) if response_data_dict["status"] == 0: order_status = 0 try: #update bank_transaction & status db.update(table_name='orders', set=f'bank_transaction="{response_data_dict["bank_transaction_id"]}", status={order_status}', search=f'order_number="{order_number}"') order_data = db.show_data("orders", "order_number", order_number) db.delete("booking", "userId", userId) # 付款成功 把booking的待預訂刪除 db.close() data = { "data": { "number": order_data[1], "payment": { "status": order_data[9], "message": "付款成功" } } } return jsonify(data) except Exception as e: #資料庫錯誤 return jsonify({"error": True, "message": str(e)}), 500 else: # response_data_dict不是0,付款失敗 order_status = 1 db.update(table_name='orders', set=f'status={order_status}', search=f'order_number="{order_number}"') order_data = db.show_data("orders", "order_number", order_number) data = { "error":True, "number": order_number, "payment": { "status": order_data[9], "message": "付款失敗" } } return jsonify(data), 400 except Exception as e: return jsonify({"error": True, "message": str(e)}), 400
def build_booking(): '''build a trip if interested''' if request.method == "POST": post_data = request.get_json() attractionId = post_data["attractionId"] date = post_data["date"] time = post_data["time"] price = post_data["price"] user_email = session.get("email") rex_date = r"(^\d{4}\-(0[1-9]|1[012])\-(0[1-9]|[12][0-9]|3[01])$)" #yyyy-mm-dd match_date = re.match(rex_date, date) date_today_check = datetime.now().strftime("%Y-%m-%d") if date == "": return jsonify({"error": True, "message": "請選擇日期"}), 400 elif date < date_today_check: return jsonify({"error": True, "message": "不可預定今天以前的日期"}), 400 if not match_date: return jsonify({"error": True, "message": "日期格式不正確"}), 400 if time == "": return jsonify({"error": True, "message": "請選擇時間"}), 400 if price == "": return jsonify({"error": True, "message": "請填入費用"}), 400 if not user_email: return jsonify({"error": True, "message": "請先登入會員"}), 403 else: try: db = DB_controller(host=DB_HOST, user=DB_USER, password=DB_PWD, db=DB_NAME) user_data = db.show_data("user", "email", user_email) userId = user_data[0] booking_data = db.show_data("booking", "userId", userId) # 先判斷booking table裡面是否已經有資料了, if booking_data: # 如果有 => 刪除原本的 insert此筆 delete = db.delete("booking", "userId", userId) insert = db.insert_data( table_name="booking", settingrow='attractionId, userId, date, time, price', settingvalue= f'"{attractionId}","{userId}","{date}", "{time}", "{price}"' ) db.close() res = make_response(jsonify({"ok": True})) return res else: # 沒找到的話直接insert insert = db.insert_data( table_name="booking", settingrow='attractionId, userId, date, time, price', settingvalue= f'"{attractionId}","{userId}","{date}", "{time}", "{price}"' ) db.close() res = make_response(jsonify({"ok": True})) return res except Exception as e: return jsonify({"error": True, "message": str(e)}), 500
def attractions(): ''' Parameter:page (int), keyword(string) each page have 12 data, input the page and keyword you wanna search, and get the data. ''' if request.method == "GET": page = request.args.get("page") keyword = request.args.get("keyword") if not page: return jsonify({"error": True, "message": "請輸入參數page"}), 500 # 有 page , page輸入判斷 try: page = int(page) except ValueError: try: # 如果是小數點,轉成整數部分來顯示 page = float(page) page = int(page) except ValueError: # 不是的話直接顯示error return jsonify({"error": True, "message": "請輸入數字"}), 500 if page < 0: # page填負數的話 return jsonify({"error": True, "message": "page number must >0"}), 500 data = [] tmp_db = [] # page 規律 start = 12 * page end = start + 12 if keyword: try: db = DB_controller( host=DB_HOST, user=DB_USER, password=DB_PWD, db=DB_NAME ) result = db.relative_data("attractions", "name", keyword) db.close() for ans in result: data_dict = { "id": ans[0], "name": ans[1], "category": ans[2], "description": ans[3], "address": ans[4], "transport": ans[5], "mrt": ans[6], "latitude": str(ans[7]), #小數點 jsonify會有問題(Decimal error),所以轉成str "longitude": str(ans[8]), "images": ans[9], } tmp_db.append(data_dict) count_data = len(tmp_db) if count_data <= 12: if page == 0: # 必須在第0頁顯示 one_page = { "nextPage": None, "data": tmp_db, } res = make_response(jsonify(one_page)) return res else: one_page = { "nextPage": None, "data": None, } res = make_response(jsonify(one_page)) return res else: # 大於12筆資料 last_page, last_page_data = count_pages(count_data) if page < last_page: # 不是最後一頁 for i in range(start, end): data.append(tmp_db[i]) one_page = { "nextPage": page+1, "data": data, } res = make_response(jsonify(one_page)) return res elif page == last_page: # 最後一頁 for i in range(start, start+last_page_data): data.append(tmp_db[i]) one_page = { "nextPage": None, "data": data, } res = make_response(jsonify(one_page)) return res else: # page > last_page one_page = { "nextPage": None, "data": None, } res = make_response(jsonify(one_page)) return res except Exception as e: return jsonify({"error": True, "message": str(e)}), 500 else: # 沒有keyword # 查詢資料庫目前有幾筆資料 try: db = DB_controller( host=DB_HOST, user=DB_USER, password=DB_PWD, db=DB_NAME ) except Exception as e: return jsonify({"error": True, "message": str(e)}), 500 count_data = db.count_data("attractions") last_page, last_page_data = count_pages(count_data) result = db.limit_data("attractions", start, 12) # 改limit分頁 LIMITE優點是假如最後一頁不足12筆資料也不會報錯,就顯示剩下的全部 db.close() for res in result: # 塞入12筆資料 data_dict = { "id": res[0], "name": res[1], "category": res[2], "description": res[3], "address": res[4], "transport": res[5], "mrt": res[6], "latitude": str(res[7]), "longitude": str(res[8]), "images": res[9], } data.append(data_dict) if page < last_page: one_page = { "nextPage": page+1, "data": data, } res = make_response(jsonify(one_page)) return res elif page == last_page: # 最後一頁 one_page = { "nextPage": None, "data": data, } res = make_response(jsonify(one_page)) return res elif page > last_page: # 大於現有頁數 one_page = { "nextPage": None, "data": None, } res = make_response(jsonify(one_page)) return res else: return jsonify({"error": True, "message": "Something wrong"}), 500
# sys.path.append("C:\\Users\\user\\Desktop\\GitHub\\taipei-day-trip-website") sys.path.append("/home/ubuntu/root/taipei-day-trip-website") # sys.path.append("/app") # 容器裡面 from model.db import DB_controller # 原本會有紅紅的底線,但在該檔案中加上__init__.py 錯誤就消失了 import os from dotenv import load_dotenv load_dotenv() DB_HOST = os.getenv("DB_HOST") DB_USER = os.getenv("DB_USER") DB_PWD = os.getenv("DB_PWD") DB_NAME = os.getenv("DB_NAME") db = DB_controller( host=DB_HOST, user=DB_USER, password=DB_PWD, db=DB_NAME) with open("taipei-attractions.json", mode="r", encoding="utf-8") as f: data = json.load(f) data = data["result"]["results"] for j in range(len(data)): data[j]["file"] = data[j]["file"].replace("http", " http") data[j]["file"] = data[j]["file"].split(" ") data[j]["file"].pop(0) clean_img = [] for i in range(len(data[j]["file"])):