db_router.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. from fastapi import APIRouter
  2. from supabase import create_client, Client
  3. from dotenv import load_dotenv
  4. import os
  5. from datetime import datetime
  6. from random import choice
  7. from openai import OpenAI
  8. from typing import Annotated
  9. from pydantic import Field
  10. client = OpenAI()
  11. load_dotenv()
  12. # supaspace 連線
  13. url: str = os.environ.get('SUPABASE_URL')
  14. key: str = os.environ.get('SUPABASE_KEY')
  15. supabase: Client = create_client(url, key)
  16. dbRouter = APIRouter()
  17. @dbRouter.get("/click")
  18. def add_click_time(click_type :str = None,brand:str = None):
  19. try:
  20. if click_type == None :
  21. response = supabase.table('click_time').select("*").eq('id', 1).execute()
  22. click_time = response.data[0]['click_time'] + 1
  23. data, count = supabase.table('click_time') \
  24. .update({'click_time':click_time,'update_time':str(datetime.now())})\
  25. .eq('id', 1)\
  26. .execute()
  27. elif click_type == "card" :
  28. response = supabase.table('click_time').select("*").eq('id', 2).execute()
  29. click_time = response.data[0]['click_time'] + 1
  30. data, count = supabase.table('click_time') \
  31. .update({'click_time':click_time,'update_time':str(datetime.now())})\
  32. .eq('id', 2)\
  33. .execute()
  34. elif click_type == "card-en" :
  35. response = supabase.table('click_time').select("*").eq('name', "國際貴賓卡-en").execute()
  36. click_time = response.data[0]['click_time'] + 1
  37. print(response)
  38. data, count = supabase.table('click_time') \
  39. .update({'click_time':click_time,'update_time':str(datetime.now())})\
  40. .eq('id', 3)\
  41. .execute()
  42. elif click_type == "click_url" and brand:
  43. response = supabase.table('101_brand').select("*").eq("name",brand).execute()
  44. click_time = response.data[0][click_type] + 1
  45. data, count = supabase.table('101_brand') \
  46. .update({click_type:click_time})\
  47. .eq("name",brand)\
  48. .execute()
  49. elif click_type == "click_address" and brand:
  50. response = supabase.table('101_brand').select("*").eq("name",brand).execute()
  51. click_time = response.data[0][click_type] + 1
  52. data, count = supabase.table('101_brand') \
  53. .update({click_type:click_time})\
  54. .eq("name",brand)\
  55. .execute()
  56. return {"state":"success","click_time" : click_time}
  57. except Exception as e:
  58. return {"state":str(e)}
  59. @dbRouter.get("/find_brand")
  60. def find_brand(keyword:str = None,language :str = "ch",page_num : int = None,page_amount: int = None,search_name : str = None):
  61. if keyword is None :
  62. query = supabase.table('101_brand').select('*').eq("language", language)
  63. else :
  64. keyword_list = keyword.split(",")
  65. query= supabase.table('101_brand').select('*').eq("language", language)
  66. for keyword_tmp in keyword_list :
  67. query = query.like('tags', f'%{keyword_tmp}%')
  68. if search_name:
  69. query = query.like('name', f'%{search_name}%')
  70. result,_ = query.order("id", desc=True).execute()
  71. count = len(result[1])
  72. if page_num and page_amount :
  73. offset = (page_num - 1) * page_amount
  74. query = query.range(offset, offset + page_amount-1)
  75. try:
  76. data,_ = query.execute()
  77. result = []
  78. for shop in data[1] :
  79. json = {
  80. "type" : shop["type"],
  81. "info" : shop
  82. }
  83. if language != "ch" :
  84. if shop["floor"] == "館外" :
  85. json["info"]["floor"] = "outside"
  86. result.append(json)
  87. return {"state":"success","all_num" : count,"data" : result}
  88. except Exception as e:
  89. return {"state":"fail","message" :str(e)}
  90. @dbRouter.get("/arviews")
  91. def arviews(start:str,end:str,language:str = "ch"):
  92. try :
  93. data, count = supabase.table('101_arviews')\
  94. .select('*')\
  95. .eq('start_loc', start) \
  96. .like('tour_place', f'%{end}%') \
  97. .execute()
  98. result :str
  99. words :str
  100. if len(data[1]) != 0:
  101. if language == "ch" :
  102. result = data[1][0]["url"]
  103. words = data[1][0]["words"]
  104. else:
  105. result = data[1][0]["en_url"]
  106. words = data[1][0]["en_words"]
  107. else :
  108. result = "no this route"
  109. return {"state":"success","url" : result,"words" : words}
  110. except Exception as e:
  111. return {"state":"fail","message" :str(e)}
  112. @dbRouter.get("/static_tickets")
  113. async def static_tickets(is_Chinese : int = None):
  114. try:
  115. data =None
  116. if is_Chinese :
  117. data, count = supabase.table('101_ticket')\
  118. .select('*')\
  119. .in_('id', [1,3,6,7])\
  120. .execute()
  121. else :
  122. data, count = supabase.table('101_ticket')\
  123. .select('*')\
  124. .in_('id', [182,183,180])\
  125. .execute()
  126. result = []
  127. for shop in data[1] :
  128. json = {
  129. "type" : shop["type"],
  130. "info" : shop
  131. }
  132. result.append(json)
  133. return {"state":"success","result" : result}
  134. except Exception as e:
  135. return {"state":"fail","message" :str(e)}
  136. @dbRouter.get("/ad/{type}")
  137. def read_root(type:str,language :str = "ch"):
  138. keyword1 :str
  139. keyword2 :str
  140. if type == "美食伴手禮":
  141. keyword1 = "餐飲"
  142. keyword2 = "伴手禮"
  143. else :
  144. keyword1 = "住宿"
  145. keyword2 = "伴手禮"
  146. data, count = supabase.table('101_brand')\
  147. .select('*')\
  148. .eq("floor","館外")\
  149. .eq("language", language)\
  150. .or_(f"tags.ilike.%{keyword1}%,tags.ilike.%{keyword2}%")\
  151. .order("id", desc=True)\
  152. .execute()
  153. result = data[1]
  154. # 從結果中隨機選擇一筆資料
  155. random_row = choice(result)
  156. if language != "ch" :
  157. if random_row["floor"] == "館外" :
  158. random_row["floor"] = "outside"
  159. #print(random_row)
  160. return {"data": random_row}
  161. @dbRouter.post("/message_not_in_cache")
  162. def message_not_in_cache(question :str ,answer :str,data_list :str='[]',client_id : str = "0" ):
  163. try:
  164. data, count = supabase.table('client_message').select('*').eq("question",question).execute()
  165. if len(data[1]) != 0 :
  166. return {"state": 200 , "message" : "have saved"}
  167. data, count = supabase.table('client_message').insert({"client_id": client_id, "question": question,"answer":answer}).execute()
  168. return {"state": 200 , "message" : "success"}
  169. except Exception as e:
  170. return {"state": 500 , "message" : str(e)}
  171. from typing import List, Optional
  172. from pydantic import BaseModel
  173. class MessageSaveRequest(BaseModel):
  174. question: str
  175. answer: str
  176. data_list: str
  177. @dbRouter.post("/message_save")
  178. def message_save(request:MessageSaveRequest):
  179. try :
  180. data, count = supabase.table("log_record").insert({
  181. "question": request.question,
  182. "answer": request.answer,
  183. "data_list": request.data_list
  184. }).execute()
  185. return {"state": 200 , "message" : "success"}
  186. except Exception as e:
  187. return {"state": 500 , "message" : str(e)}
  188. from pydantic import BaseModel, EmailStr
  189. import base64
  190. import pickle
  191. from email.mime.text import MIMEText
  192. from google.auth.transport.requests import Request
  193. from google.oauth2.credentials import Credentials
  194. from google_auth_oauthlib.flow import InstalledAppFlow
  195. from googleapiclient.discovery import build
  196. import os
  197. SCOPES = ['https://www.googleapis.com/auth/gmail.send']
  198. class dataform(BaseModel):
  199. title: str
  200. content: str
  201. client_name: str
  202. gender: str
  203. email: EmailStr
  204. phone: str
  205. type:str
  206. def send_email(to_email,from_email,message):
  207. creds = None
  208. # 如果存在 token.pickle 文件,讀取
  209. if os.path.exists('token.pickle'):
  210. with open('token.pickle', 'rb') as token:
  211. creds = pickle.load(token)
  212. # 如果沒有有效的憑據,就進行登入
  213. if not creds or not creds.valid:
  214. if creds and creds.expired and creds.refresh_token:
  215. creds.refresh(Request())
  216. else:
  217. flow = InstalledAppFlow.from_client_secrets_file(
  218. 'credentials.json', SCOPES)
  219. creds = flow.run_local_server(port=0)
  220. # 保存憑據
  221. with open('token.pickle', 'wb') as token:
  222. pickle.dump(creds, token)
  223. service = build('gmail', 'v1', credentials=creds)
  224. # 設定郵件
  225. message = MIMEText(message)
  226. message['to'] = to_email
  227. message['from'] = from_email
  228. message['subject'] = '101 ai客服 表單新資料'
  229. raw = base64.urlsafe_b64encode(message.as_bytes()).decode()
  230. # 發送郵件
  231. try:
  232. message = service.users().messages().send(userId='me', body={'raw': raw}).execute()
  233. print(f'已發送郵件: {message["id"]}')
  234. return "success"
  235. except Exception as error:
  236. print(f'發送郵件時出錯: {error}')
  237. return "fail"
  238. @dbRouter.post("/insert_table")
  239. def insert_table(data: dataform):
  240. try:
  241. response,count = supabase.table('lost_property').insert(data.dict()).execute()
  242. email_content = f"問題類別:{response[1][0]['type']}\n標題:{response[1][0]['title']}\n內容:{response[1][0]['content']}\n姓名:{response[1][0]['client_name']}\n性別:{response[1][0]['gender']}\n電子郵件:{response[1][0]['email']}\n聯絡電話:{response[1][0]['phone']}\n"
  243. try:
  244. send_email("mallservice@tfc101.com.tw","mia@choozmo.com",str(email_content)) # mallservice@tfc101.com.tw
  245. except Exception as e:
  246. print(str(e))
  247. return {"state": 200 ,"message": "資料已成功提交"}
  248. except Exception as e:
  249. return {"state": 500 , "message" : str(e)}
  250. @dbRouter.post("/video_save_into_cache")
  251. def message_not_in_cache(video_name : Annotated[str, Field(description="檔案請丟進/home/mia/101/static/video_cache/others/資料夾裡")],client_message_id :str = None,question:str = None):
  252. try:
  253. data = []
  254. if client_message_id :
  255. data, count = supabase.table('client_message').select('*').eq("id",client_message_id).execute()
  256. elif question:
  257. data, count = supabase.table('client_message').select('*').eq("question",question).execute()
  258. info = data[1][0]
  259. response = supabase.table('video_cache').insert({"question": info["question"],"answer":info["answer"],"video_url":f"/static/video_cache/others/{video_name}"}).execute()
  260. response = supabase.table('client_message').delete().eq('id', info["id"]).execute()
  261. return {"state": 200 , "message" : "success"}
  262. except Exception as e:
  263. return {"state": 500 , "message" : str(e)}
  264. from sherry.semantic_search import ask_question
  265. @dbRouter.post("/video_cache")
  266. def video_cache(client_message :str ):
  267. try:
  268. # data, count = supabase.table('video_cache').select('*').like('question', f'%{client_message}%').execute()
  269. # if len(data[1]) == 0 :
  270. # return {"state": 500 , "message" : "no data"}
  271. # return {"state": 200 , "message" : data[1]}
  272. result = ask_question(client_message)
  273. # result[0]["answer"]
  274. if result == None :
  275. return {"state": 500 , "message" : "no data"}
  276. data, count = supabase.table("log_record").insert({"question":client_message, "answer":result[0]["answer"]}).execute()
  277. return {"state": 200 , "message" : result }
  278. except Exception as e:
  279. return {"state": 500 , "message" : str(e)}