[暑訓網站開發日常]

Tags
izcc
Last edited
Aug 7, 2022 06:55 AM
by:陳澤榮 (timothychenpc@gmail.com)
 
這個網站本身時用於四校聯合暑訓(楓落景畔遇建成),然後仍然沒有採用RESTful的方式設計api,所以忍耐一下😂

基本資訊

  • 網址
  • Github位置
  • Hackmd

目標

功能

  • 介紹暑訓的內容(暑訓的時間,內容,友社以及報名資訊等)
  • 報名功能(要可以進行檔案上傳)

開發

頁面以及路由設計

主頁 / [get]

這個頁面的設計和製作都是由WhiteCat進行的,但是因為是使用react框架(採用js渲染html的元素)進行的前端的撰寫,因為不是傳統的htmlcss的格式,所以在和後端flask合併的過程中有很多的問題出現(也常常會出現跟flask的模板引擎Jinja2打架的情況)

報名表單 /join [get, post]

這個頁面因為需要進行表單驗證(同時包含csrf_token)所以這邊我們使用htmlcss重新寫了一次,然後這次網站的報名因為想要跟一般傳統的google表單所搭建的報名做出區別,所以我們就一樣需要去找其他的儲存空間(但是因為我個人比較熟NoSQL所以最終採用Mongodb作為所有內容的儲存)
 
然後這個路由支援兩個方法一個是一般的get一個是post請求,而post請求主要就是因為表單是通過post請求封裝在request body進行傳輸的,然後表單驗證的部分分為以下兩個部分:
 
  • 一般的表單內容
一般表單內容的部分我是採用wtforms進行後端驗證(前端只有進行required驗證),
然後wtforms的好處就是你可以使用物件的方式構建你的表單,然後再使用jinja2插入到html中渲染整個表單的內容(而且還自帶csrf_token的功能)
notion image
 
  • 小黃卡的檔案
這邊進行檔案內容的上傳因為檔案的大小絕對不會超過16MB所以我就沒有使用GridFS而是直接使用一般的document進行儲存,然後在整個檔案上傳和處理的部分會經過幾個步驟:
  • 上傳檔案
  • 檢查檔案大小(限制每個檔案3MB) 如果檔案大小超過3MB則會觸發http 413的錯誤(比較高層級的錯誤),然後可以自定義error handler去管理頁面
  • 檢查檔案格式(pdf, png, jpg, jpeg, HEIC) 不符合則在產生回應的時候客製化進行回應(檔案格式不符合)
  • 檔案名稱(避免因為空格或者斜線影響到檔案系統的儲存,類似注入) 這邊是使用werkzeug.utils套件的secure_filename將檔案名稱安全化
  • 寫入暫存 因為好像沒有辦法直接將內容進行上傳(沒有找到獲取那個file物件的原數據的方法)
  • 將檔案上傳到mongodb 這邊就是比較一般的上傳只是上傳的內容都是二進制的檔案內容
  • 清除暫存
*HEIC是iphone的圖片檔案格式
notion image

數據庫設計

mongodb └───izcc捷大(DB) │ └───games(Collection) │ └───settings(Collection) └───izcc_join報名網站(DB) │ └───data 一般資料(Collection) │ └───file 小黃卡資料(Collection)
這次一樣是採用NoSQL作為這次的主要的儲存,然後以上是這次網站的數據庫架構,然後可以發現最主要報名的內容都是放在datafile這兩個collection中,針對於檔案儲存的部分,這次沒有考慮使用blob之類的東西,想要直接一次都存放在mongodb中,而mongodb支援兩種檔案存儲的方式:
  • 一個document放一個檔案的數據(16mb以內)
  • 使用gridFS針對檔案進行切分,放在不同的document16mb以上)
因為這次所有需要儲存的檔案只有圖片(小黃卡),所以可以直接使用第一種方案,使用單一document管理我們的數據。
 
這個是Mongodb Compass中查看的izcc_join這個db的內容(還好mongodb給的500mb的免費空間很夠用)
這個是Mongodb Compass中查看的izcc_join這個db的內容(還好mongodb給的500mb的免費空間很夠用)

檔案設計

izcc2022summer | README.md 說明文件 | download_file.py 輸出名單+下載小黃卡 | requirements.txt 依賴資源 | app.py 主程式(包含伺服器設定) | └───main 主要後端檔案的所在 | | __init__.py | | model.py 進行物件設計 | | forms.py 表單驗證 | | routes.py 路由管理 └───static 靜態資料 │ └───js │ └───css │ └───media 影像資源 └───templates html檔案 │ | index.html │ | join.html

debug設計

這次比較沒有設計完整系統性的debug的終端機輸出,但是有針對報名的結果使用line notify 對目前狀況進行掌握(在報名成功的時候傳送姓名,出錯的時候傳送錯誤訊息等)。但是之後還是要研究如何針對每一個請求的處理過程進行解析,才能更有效率地進行debug以及更快速的掌握問題的發生。
另外一點就是雲端部署時的終端機資訊掌握(因為沒有這些內容基本上在雲端環境發生的問題就會根本沒有辦法進行分析跟解決)。

成果

主頁

notion image
 
notion image
notion image
notion image
notion image
notion image
notion image

報名

 
notion image
notion image
notion image

心得

K(keep)

  • 數據庫結構的設計 (有將一般的資料跟檔案分開,避免存取一般資料的時候因為需要載入的內容過大而卡頓)
  • 有學會檔案存儲
  • 有串接line notify在報名成功和報錯的時候進行反饋 (可以不用使用電腦就可以了解目前的情況,提高了debug等的效率)
  • 開發過程迅速
  • 有為了在mongodb存儲檔案開發輸出工具 (download_file.py用於將用戶資料輸出excel,並將所有在mongodb中以二進制存儲的檔案數據轉成對應的檔案格式輸出)
 

C(challenge)

  • reactflask的合併
  • 修改react產生的js (整個過程跟打ctf一樣刺激) 就連改一下文字,因為這個檔案沒有中文(只有unicode),所以還要encodeunicode然後搜索,然後修改
    • notion image
 
  • 檔案存儲 (因為之前真的完全沒有嘗試過再mongodb儲存完整的檔案)
  • 多人協作

S(stop)

  1. 沒有了解原理、只為了目的
  1. 沒有做好debug資料的管理 (可能需要更全面和不同時間段的debug資料)
  1. 不會reactflask合併
  1. 沒有好好管理相關的路由和方法
  1. 有些操作沒有考慮好使用者回饋 (讓使用者對目前的狀態感到困惑)
  1. 沒有設計好多人協作的workflow (導致有時候沒有辦法通過git pull push完成合併等問題,最後還是會通過dc進行檔案的傳輸或者是從zip找檔案來使用)
  1. 每次都在重複寫一些功能 (下載,輸出excel之類的)

S(start)

  1. 搞清楚decorators的原理
  1. 可能要想辦法有效率地輸出每一個請求的處理過程 (包含經過哪些函式,每一個函式分別的inputoutput是什麼)
  1. 要去搞清楚react怎麼跟flask合併
  1. 可能要採用RESTful的方式針對api進行管理 (通過httpmethod區分不同的用途,然後用物件式進行處理)
  1. 多使用彈窗隊使用者進行回饋
  1. 可能需要規範workflow (包含什麼時候需要commit,什麼時候需要進行merge之類的,然後避免git以外的操作)
  1. 考慮構建自己的tool kit (然後將功能進行封裝,然後需要的時候可以直接調用,避免重複寫)