使用Python Flask建置影像圖檔上傳網站服務(五):使用日期時間重設上傳檔名

本文將改寫Python Flask網站伺服器檔案上傳程式,設置一個新路由“/esp32cam”,接收ESP32CAM微電腦控制板上傳的影像檔,並且將影像檔用上傳的日期與時間重新命名儲存。

Python Flask接收ESP32CAM上傳影樣檔

處理上傳檔案的程式碼,之前是寫在首頁’/路由的’upload_file()函式,像這樣:

根路徑路由

新增處理ESP32CAM控制板上傳影像的程式,跟之前處理網頁上傳檔案的程式,基本上是一樣的,所以筆者把處理上傳檔案的程式碼放在另一個“handle_file”自訂函式。

handle_file()函式接收一個request(請求)物件,然後依照上傳檔的處理情況,傳回「字典」型態的資料,其中的“msg”包含狀態訊息,若上傳檔案處理成功,msg成員的值將是“ok”,而filename成員的值將是上傳檔的名字。

改成呼叫handle_file()函式處理上傳檔的“/”路由程式碼如下:

修改後的根路徑

用當前的日期時間設定上傳檔名

為了避免檔名重複,handle_file()自訂函式會將每個上傳檔的名字改成當前的日期和時間。datetime模組的datetime.now()函式可傳回當前的日期與時間,透過str()函式將它轉成字串;因為Windows系統的檔名不可包含“:”字元,因此最後透過字串物件的replace()方法,把字串裡的所有“:”都替換成“_”。

把當前的日期時間轉成字串

處理上傳檔案的handle_file函式

底下是handle_file()函式的程式碼,唯有檔案上傳成功,它才會傳回檔名。

def handle_file(request):
    if 'filename' not in request.files:
        return {"msg": 'no_file'}  # 傳回代表「沒有檔案」的訊息

    file = request.files['filename']  # 取得上傳檔

    if file.filename == '':
        return {"msg": 'empty'}       # 傳回代表「空白」的訊息

    if file:
        file_type = filetype.guess_extension(file)  # 判斷上傳檔的類型

        if file_type in ALLOWED_EXTENSIONS:
            file.stream.seek(0)
            # filename = secure_filename(file.filename)
            # 重新設定檔名:日期時間 + ‘.’ + ‘副檔名’
            filename = str(datetime.datetime.now()).replace(
                ':', '_') + '.' + file_type
            file.save(os.path.join(
                app.config['UPLOAD_FOLDER'], filename))
            # 傳回代表上傳成功的訊息以及檔名。
            return {"msg": 'ok', "filename": filename}
        else:
            return {"msg": 'type_error'}  # 傳回代表「檔案類型錯誤」的訊息

處理ESP32CAM控制板上傳檔案的路由

處理ESP32CAM上傳檔案的“/esp32cam”路由程式,只需把連線請求轉給handle_file()函式,再把函式傳回的訊息發送給用戶端(ESP32CAM開發板)。

處理ESP32CAM控制板上傳檔案的路由

修改之後的完整Python Flask網站伺服器程式碼(app.py檔)如下:

import datetime
import os
import pathlib
import filetype
from flask import Flask, flash, request, redirect, url_for, render_template
from werkzeug.utils import secure_filename

# 取得目前檔案所在的資料夾
SRC_PATH = pathlib.Path(__file__).parent.absolute()
UPLOAD_FOLDER = os.path.join(SRC_PATH, 'static', 'uploads')

app = Flask(__name__)
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'     # 請自行修改密鑰
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 3 * 1024 * 1024

ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/', methods=['POST'])
def upload_file():
    res = handle_file(request)

    if res['msg'] == 'ok':
        flash('影像上傳完畢!')
        return render_template('index.html', filename=res['filename'])
    elif res['msg'] == 'type_error':
        flash('僅允許上傳png, jpg, jpeg和gif影像檔')
    elif res['msg'] == 'empty':
        flash('請選擇要上傳的影像')
    elif res['msg'] == 'no_file':
        flash('沒有上傳檔案')

    return redirect(url_for('index'))  # 令瀏覽器跳回首頁


@app.route('/esp32cam', methods=['POST'])
def esp32cam():
    res = handle_file(request)
    return res['msg']


def handle_file(request):
    if 'filename' not in request.files:
        return {"msg": 'no_file'}  # 傳回代表「沒有檔案」的訊息

    file = request.files['filename']  # 取得上傳檔

    if file.filename == '':
        return {"msg": 'empty'}       # 傳回代表「空白」的訊息

    if file:
        file_type = filetype.guess_extension(file)  # 判斷上傳檔的類型

        if file_type in ALLOWED_EXTENSIONS:
            file.stream.seek(0)
            # filename = secure_filename(file.filename)
            # 重新設定檔名:日期時間 + ‘.’ + ‘副檔名’
            filename = str(datetime.datetime.now()).replace(
                ':', '_') + '.' + file_type
            file.save(os.path.join(
                app.config['UPLOAD_FOLDER'], filename))
            # 傳回代表上傳成功的訊息以及檔名。
            return {"msg": 'ok', "filename": filename}
        else:
            return {"msg": 'type_error'}  # 傳回代表「檔案類型錯誤」的訊息


@app.route('/img/<filename>')
def display_image(filename):
    return redirect(url_for('static', filename='uploads/' + filename))


if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)
Posts created 470

3 thoughts on “使用Python Flask建置影像圖檔上傳網站服務(五):使用日期時間重設上傳檔名

  1. 您好,想請教我應該如何讓ESP32-CAM拍照後將照片上傳至FLASK,並請FLASK上傳雲端辨識訓練模型,並回傳訊息至資料庫(先不管資料庫這一段),我目前遇到無法讓ESP32去連結flask,參考您的程式,__file__,這個我也無法定義,應該怎麼做比較好?

    1. 這是一個HTTP前端(ESP32)+ 後端(Flask)的應用,建議分開除錯,例如,編寫一個透過HTML表單上傳影像的Flask伺服器程式,確認OK,再測試ESP32的上傳影像程式是否正常。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top