main_tmp.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. # fastapi
  2. from fastapi import FastAPI, Request, Response, HTTPException, status, Depends , Form
  3. from fastapi import templating
  4. from fastapi.templating import Jinja2Templates
  5. from fastapi.responses import HTMLResponse, RedirectResponse, JSONResponse
  6. from fastapi.middleware.cors import CORSMiddleware
  7. from fastapi.staticfiles import StaticFiles
  8. # fastapi view function parameters
  9. from typing import List, Optional
  10. import json
  11. # path
  12. import sys
  13. # time
  14. # import datetime
  15. from datetime import timedelta, datetime
  16. # db
  17. import dataset
  18. from passlib import context
  19. import models
  20. from random import randint
  21. # authorize
  22. from passlib.context import CryptContext
  23. pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
  24. import jwt
  25. from fastapi_jwt_auth import AuthJWT
  26. from fastapi_jwt_auth.exceptions import AuthJWTException
  27. from fastapi.security import OAuth2AuthorizationCodeBearer, OAuth2PasswordRequestForm
  28. import numpy as np
  29. import pymysql
  30. pymysql.install_as_MySQLdb()
  31. db_settings = {
  32. "host": "db.ptt.cx",
  33. "port": 3306,
  34. "user": "choozmo",
  35. "password": "pAssw0rd",
  36. "db": "Water_tower",
  37. "charset": "utf8mb4"
  38. }
  39. # app
  40. app = FastAPI()
  41. app.add_middleware(
  42. CORSMiddleware,
  43. allow_origins=["*"],
  44. allow_credentials=True,
  45. allow_methods=["*"],
  46. allow_headers=["*"],
  47. )
  48. SECRET_KEY = "df2f77bd544240801a048bd4293afd8eeb7fff3cb7050e42c791db4b83ebadcd"
  49. ALGORITHM = "HS256"
  50. ACCESS_TOKEN_EXPIRE_MINUTES = 3000
  51. pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
  52. #
  53. app.mount(path='/templates', app=StaticFiles(directory='templates'), name='templates')
  54. app.mount(path='/static', app=StaticFiles(directory='static'), name='static ')
  55. #
  56. templates = Jinja2Templates(directory='templates')
  57. @AuthJWT.load_config
  58. def get_config():
  59. return models.Settings()
  60. # view
  61. @app.get('/', response_class=HTMLResponse)
  62. async def index(request: Request):
  63. print(request)
  64. return templates.TemplateResponse(name='index.html', context={'request': request})
  65. @app.get('/login', response_class=HTMLResponse)
  66. async def login(request: Request):
  67. return templates.TemplateResponse(name='login_test.html', context={'request': request})
  68. @app.post("/login")
  69. async def login_for_access_token(request: Request, form_data: OAuth2PasswordRequestForm = Depends(), Authorize: AuthJWT = Depends()):
  70. db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/Water_tower?charset=utf8mb4')
  71. user = authenticate_user(form_data.username, form_data.password)
  72. if not user:
  73. raise HTTPException(
  74. status_code=status.HTTP_401_UNAUTHORIZED,
  75. detail="Incorrect username or password",
  76. headers={"WWW-Authenticate": "Bearer"},
  77. )
  78. access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
  79. access_token = create_access_token(
  80. data={"sub": user.username}, expires_delta=access_token_expires
  81. )
  82. table = db['users']
  83. user.token = access_token
  84. print(user)
  85. table.update(dict(user), ['username'])
  86. access_token = Authorize.create_access_token(subject=user.username)
  87. refresh_token = Authorize.create_refresh_token(subject=user.username)
  88. Authorize.set_access_cookies(access_token)
  89. Authorize.set_refresh_cookies(refresh_token)
  90. #return templates.TemplateResponse("home.html", {"request": request, "msg": 'Login'})
  91. return {"access_token": access_token, "token_type": "bearer"} # 回傳token給前端
  92. @app.get('/register', response_class=HTMLResponse)
  93. async def login(request: Request):
  94. return templates.TemplateResponse(name='rigister_test.html', context={'request': request})
  95. @app.post('/register')
  96. async def register(request: Request, form_data: OAuth2PasswordRequestForm = Depends()):
  97. user = models.User(**await request.form())
  98. print(form_data.username, form_data.password, user)
  99. user.id = randint(1000, 9999)
  100. user.isAdmin = 0 #預設為非管理者
  101. user.roleType = 0 #預設為employee
  102. # 密碼加密
  103. #user.password = get_password_hash(user.password)
  104. # 存入DB
  105. db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/Water_tower?charset=utf8mb4')
  106. user_table = db['users']
  107. user_table.insert(dict(user))
  108. # 跳轉頁面至登入
  109. return templates.TemplateResponse(name='login.html', context={'request': request})
  110. @app.get('/home', response_class=HTMLResponse)
  111. async def home(request: Request):
  112. return templates.TemplateResponse(name='home.html', context={'request': request})
  113. @app.get('/tower', response_class=HTMLResponse)
  114. async def tower(request: Request, Authorize: AuthJWT = Depends()):
  115. try:
  116. Authorize.jwt_required()
  117. except Exception as e:
  118. print(e)
  119. return RedirectResponse('/login')
  120. # current_user = Authorize.get_jwt_subject()
  121. return templates.TemplateResponse(name='tower.html', context={'request': request})
  122. @app.get('/optim', response_class=HTMLResponse)
  123. async def optim(request: Request, Authorize: AuthJWT = Depends()):
  124. try:
  125. Authorize.jwt_required()
  126. except Exception as e:
  127. print(e)
  128. return RedirectResponse('/login')
  129. # current_user = Authorize.get_jwt_subject()
  130. return templates.TemplateResponse(name='optim.html', context={'request': request})
  131. @app.get('/vibration', response_class=HTMLResponse)
  132. async def vibration(request: Request, Authorize: AuthJWT = Depends()):
  133. try:
  134. Authorize.jwt_required()
  135. except Exception as e:
  136. print(e)
  137. return RedirectResponse('/login')
  138. # current_user = Authorize.get_jwt_subject()
  139. return templates.TemplateResponse(name='vibration.html', context={'request': request})
  140. @app.get('/history', response_class=HTMLResponse)
  141. async def history(request: Request, Authorize: AuthJWT = Depends()):
  142. try:
  143. Authorize.jwt_required()
  144. except Exception as e:
  145. print(e)
  146. return RedirectResponse('/login')
  147. # current_user = Authorize.get_jwt_subject()
  148. return templates.TemplateResponse(name='history.html', context={'request': request})
  149. @app.get('/device', response_class=HTMLResponse)
  150. async def device(request: Request, Authorize: AuthJWT = Depends()):
  151. try:
  152. Authorize.jwt_required()
  153. except Exception as e:
  154. print(e)
  155. return RedirectResponse('/login')
  156. # current_user = Authorize.get_jwt_subject()
  157. return templates.TemplateResponse(name='device.html', context={'request': request})
  158. @app.get('/system', response_class=HTMLResponse)
  159. async def system(request: Request, Authorize: AuthJWT = Depends()):
  160. try:
  161. Authorize.jwt_required()
  162. except Exception as e:
  163. print(e)
  164. return RedirectResponse('/login')
  165. # current_user = Authorize.get_jwt_subject()
  166. return templates.TemplateResponse(name='system.html', context={'request': request})
  167. @app.get('/member', response_class=HTMLResponse)
  168. async def get_member(request: Request, Authorize: AuthJWT = Depends()):
  169. """獲取所有帳號資訊"""
  170. try:
  171. Authorize.jwt_required()
  172. except Exception as e:
  173. print(e)
  174. return RedirectResponse('/login')
  175. db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/Water_tower?charset=utf8mb4')
  176. statement = 'SELECT id,username,isAdmin,roleType FROM users'
  177. json_dic = {}
  178. for row in db.query(statement):
  179. #print(row['id'],row['username'])
  180. json_dic[row['username']] = {'isAdmin':row['isAdmin'],'roleType':row['roleType']}
  181. result = json.dumps(json_dic,ensure_ascii=False)
  182. current_user = Authorize.get_jwt_subject()
  183. print(current_user)
  184. return result
  185. @app.get('/member/edit', response_class=HTMLResponse)
  186. async def login(request: Request, Authorize: AuthJWT = Depends()):
  187. try:
  188. Authorize.jwt_required()
  189. except Exception as e:
  190. print(e)
  191. return RedirectResponse('/login')
  192. return templates.TemplateResponse(name='member_edit_test.html', context={'request': request})
  193. @app.get('/member_delete', response_class=HTMLResponse)
  194. async def login(request: Request, Authorize: AuthJWT = Depends()):
  195. try:
  196. Authorize.jwt_required()
  197. except Exception as e:
  198. print(e)
  199. return RedirectResponse('/login')
  200. return templates.TemplateResponse(name='delete_member_test2.html', context={'request': request})
  201. @app.post('/member_delete')
  202. async def delete_member(request: Request,Authorize: AuthJWT = Depends()):
  203. """刪除成員"""
  204. try:
  205. Authorize.jwt_required()
  206. except Exception as e:
  207. print(e)
  208. return RedirectResponse('/login')
  209. del_user = await request.form()
  210. current_user = Authorize.get_jwt_subject()
  211. delete_one = del_user.del_username
  212. db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/Water_tower?charset=utf8mb4')
  213. statement = 'SELECT isAdmin FROM users WHERE userName = "'+current_user+'"'
  214. for row in db.query(statement):
  215. if row['isAdmin']!=1:
  216. return {'msg': ' 你沒有權限'}
  217. else:
  218. current_user_roleType = 0
  219. del_user_roleType = -1
  220. statement = 'SELECT roleType FROM users WHERE userName = "'+current_user+'"'
  221. for row in db.query(statement):
  222. current_user_roleType = row['roleType']
  223. statement = 'SELECT roleType FROM users WHERE userName = "'+delete_one+'"'
  224. for row in db.query(statement):
  225. del_user_roleType = row['roleType']
  226. if del_user_roleType == -1:
  227. return {'msg':'不存在使用者'}
  228. elif current_user_roleType<=del_user_roleType :
  229. return {'msg': ' 你沒有權限'}
  230. else :
  231. statement = 'DELETE FROM users WHERE userName = "'+delete_one+'"'
  232. db.query(statement)
  233. return {'msg': ' 成功刪除'}
  234. @app.get('/member/authority', response_class=HTMLResponse)
  235. async def member_authority(request: Request,Authorize: AuthJWT = Depends()):
  236. """設定成員權限"""
  237. try:
  238. Authorize.jwt_required()
  239. except Exception as e:
  240. print(e)
  241. return RedirectResponse('/login')
  242. return templates.TemplateResponse(name='member_authority_test.html', context={'request': request})
  243. @app.post('/member/authority')
  244. async def member_authority(request: Request,Authorize: AuthJWT = Depends()):
  245. del_user = await request.form()
  246. current_user = Authorize.get_jwt_subject()
  247. delete_one = del_user.del_username
  248. db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/Water_tower?charset=utf8mb4')
  249. statement = 'SELECT isAdmin FROM users WHERE userName = "'+current_user+'"'
  250. await request.form()
  251. # 溫度API
  252. @app.get('/temperature')
  253. async def get_temperatures():
  254. """ 撈DB溫度 """
  255. return {'hot_water': 30.48, 'cold_water': 28.10, 'wet_ball': 25.14}
  256. @app.post("/example")
  257. async def example(request: Request,Authorize: AuthJWT = Depends()):
  258. try:
  259. Authorize.jwt_required()
  260. except Exception as e:
  261. print(e)
  262. current_user = Authorize.get_jwt_subject()
  263. #form_data = await request.form()
  264. print( current_user)
  265. return current_user
  266. @app.post('/user')
  267. def user(Authorize: AuthJWT = Depends()):
  268. Authorize.jwt_required()
  269. current_user = Authorize.get_jwt_subject()
  270. return {"user": current_user}
  271. @app.get("/example", response_class=HTMLResponse)
  272. async def example(request: Request,Authorize: AuthJWT = Depends()):
  273. try:
  274. Authorize.jwt_required()
  275. except Exception as e:
  276. print(e)
  277. return RedirectResponse('/login')
  278. current_user = Authorize.get_jwt_subject()
  279. print( current_user)
  280. return current_user
  281. @app.get('/health')
  282. async def get_health(date: str):
  283. """ 撈健康指標、預設健康指標 """
  284. date = str(datetime.strptime(date, "%Y-%m-%d"))[:10]
  285. print(date)
  286. print(str(datetime.today()))
  287. print(str(datetime.today()-timedelta(days=1)))
  288. fake_data = {
  289. str(datetime.today())[:10]: {'curr_health': 0.7, 'pred_health': 0.8},
  290. str(datetime.today()-timedelta(days=1))[:10]: {'curr_health': 0.6, 'pred_health': 0.7},
  291. }
  292. return fake_data[date]
  293. @app.get('/history_data')
  294. async def get_history(time_end: str):
  295. """ 透過終點時間,抓取歷史資料。 """
  296. date = str(datetime.strptime(time_end, "%Y-%m-%d"))[:10]
  297. print(date)
  298. print(str(datetime.today()))
  299. print(str(datetime.today()-timedelta(days=1)))
  300. fake_data = {
  301. str(datetime.today())[:10]: {
  302. 'curr_history': {
  303. 'RPM_1X': list(np.random.rand(13)),
  304. 'RPM_2X': list(np.random.rand(13)),
  305. 'RPM_3X': list(np.random.rand(13)),
  306. 'RPM_4X': list(np.random.rand(13)),
  307. 'RPM_5X': list(np.random.rand(13)),
  308. 'RPM_6X': list(np.random.rand(13)),
  309. 'RPM_7X': list(np.random.rand(13)),
  310. 'RPM_8X': list(np.random.rand(13)),
  311. 'Gear_1X': list(np.random.rand(13)),
  312. 'Gear_2X': list(np.random.rand(13)),
  313. 'Gear_3X': list(np.random.rand(13)),
  314. 'Gear_4X': list(np.random.rand(13)),
  315. },
  316. 'past_history': {
  317. 'RPM_1X': list(np.random.rand(13)),
  318. 'RPM_2X': list(np.random.rand(13)),
  319. 'RPM_3X': list(np.random.rand(13)),
  320. 'RPM_4X': list(np.random.rand(13)),
  321. 'RPM_5X': list(np.random.rand(13)),
  322. 'RPM_6X': list(np.random.rand(13)),
  323. 'RPM_7X': list(np.random.rand(13)),
  324. 'RPM_8X': list(np.random.rand(13)),
  325. 'Gear_1X': list(np.random.rand(13)),
  326. 'Gear_2X': list(np.random.rand(13)),
  327. 'Gear_3X': list(np.random.rand(13)),
  328. 'Gear_4X': list(np.random.rand(13)),
  329. }
  330. },
  331. str(datetime.today()-timedelta(days=1))[:10]: {
  332. 'curr_history': {
  333. 'RPM_1X': list(np.random.rand(13)),
  334. 'RPM_2X': list(np.random.rand(13)),
  335. 'RPM_3X': list(np.random.rand(13)),
  336. 'RPM_4X': list(np.random.rand(13)),
  337. 'RPM_5X': list(np.random.rand(13)),
  338. 'RPM_6X': list(np.random.rand(13)),
  339. 'RPM_7X': list(np.random.rand(13)),
  340. 'RPM_8X': list(np.random.rand(13)),
  341. 'Gear_1X': list(np.random.rand(13)),
  342. 'Gear_2X': list(np.random.rand(13)),
  343. 'Gear_3X': list(np.random.rand(13)),
  344. 'Gear_4X': list(np.random.rand(13)),
  345. },
  346. 'past_history': {
  347. 'RPM_1X': list(np.random.rand(13)),
  348. 'RPM_2X': list(np.random.rand(13)),
  349. 'RPM_3X': list(np.random.rand(13)),
  350. 'RPM_4X': list(np.random.rand(13)),
  351. 'RPM_5X': list(np.random.rand(13)),
  352. 'RPM_6X': list(np.random.rand(13)),
  353. 'RPM_7X': list(np.random.rand(13)),
  354. 'RPM_8X': list(np.random.rand(13)),
  355. 'Gear_1X': list(np.random.rand(13)),
  356. 'Gear_2X': list(np.random.rand(13)),
  357. 'Gear_3X': list(np.random.rand(13)),
  358. 'Gear_4X': list(np.random.rand(13)),
  359. }
  360. },
  361. }
  362. return fake_data[date]
  363. # Login funtion part
  364. def check_user_exists(username):
  365. db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/Water_tower?charset=utf8mb4')
  366. if int(next(iter(db.query('SELECT COUNT(*) FROM Water_tower.users WHERE userName = "'+username+'"')))['COUNT(*)']) > 0:
  367. return True
  368. else:
  369. return False
  370. def get_user(username: str):
  371. """ 取得使用者資訊(Model) """
  372. db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/Water_tower?charset=utf8mb4')
  373. if not check_user_exists(username): # if user don't exist
  374. return False
  375. user_dict = next(
  376. iter(db.query('SELECT * FROM Water_towe.users where userName ="'+username+'"')))
  377. user = models.User(**user_dict)
  378. return user
  379. def user_register(user):
  380. db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/Water_tower?charset=utf8mb4')
  381. table = db['users']
  382. #user.password = get_password_hash(user.password)
  383. table.insert(dict(user))
  384. def get_password_hash(password):
  385. """ 加密密碼 """
  386. return pwd_context.hash(password)
  387. def verify_password(plain_password, hashed_password):
  388. """ 驗證密碼(hashed) """
  389. return pwd_context.verify(plain_password, hashed_password)
  390. def authenticate_user(username: str, password: str):
  391. """ 連線DB,讀取使用者是否存在。 """
  392. db = dataset.connect('mysql://choozmo:pAssw0rd@db.ptt.cx:3306/Water_tower?charset=utf8mb4')
  393. if not check_user_exists(username): # if user don't exist
  394. return False
  395. user_dict = next(iter(db.query('SELECT * FROM Water_tower.users where userName ="'+username+'"')))
  396. user = models.User(**user_dict)
  397. #if not verify_password(password, user.password):
  398. #return False
  399. return user
  400. def create_access_token(data: dict, expires_delta: Optional[timedelta] = None):
  401. """ 創建token,並設定過期時間。 """
  402. to_encode = data.copy()
  403. if expires_delta:
  404. expire = datetime.utcnow() + expires_delta
  405. else:
  406. expire = datetime.utcnow() + timedelta(minutes=15)
  407. to_encode.update({"exp": expire})
  408. encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
  409. return encoded_jwt