のこりの処理
mainの全体像
main.py
from flask import Flask, redirect, jsonify, url_for, render_template, request, session
from flask_bcrypt import Bcrypt
import datetime
import user
import event
import driveFile
import photoBase
import paticip
import os
import json
app = Flask(__name__)
bcrypt = Bcrypt(app)
app.secret_key = 'ameamefurefure'
app.permanent_session_lifetime = datetime.timedelta(minutes=3)
@app.route("/login", methods = ["POST", "GET"])
def login():
if request.method == "POST":
session.permanent = True
userid = request.form.get("id")
password = request.form.get("password")
passByte = bcrypt.generate_password_hash(password=password)
passHash = passByte.decode('utf-8')
if request.form.get("signin"):
# 存在チェック
users = user.User()
checkid = users.getUser({"id":userid})
if checkid.count > 0 and userid == checkid.items[0].get("id"):
if bcrypt.check_password_hash(checkid.items[0].get("password"),password):
session["id"] = userid
return redirect(url_for("top"))
else:
return render_template("login.html",errmess="idまたはpasswordが違います")
else:
return render_template("login.html",errmess="idまたはpasswordが違います")
elif request.form.get("signup"):
# 存在チェック
users = user.User()
checkid = users.getUser({"id":userid})
if checkid != "" and passHash != "":
if userid in [i['id'] for i in checkid.items]:
return render_template("login.html",errmess="idがすでに使われています")
else:
users.newUser(userid,passHash)
session["id"] = userid
return render_template("signup.html",id=userid)
else:
return render_template("login.html",errmess="idを指定してください")
# login済みであれば入場できる
else:
if "id" in session:
return redirect(url_for("top"))
return render_template("login.html")
@app.route("/", methods=["GET","POST"])
def top():
"""
login済であればイベント一覧やメッセージを見ることができる
"""
if "id" in session:
events = event.Event()
t = datetime.date.today()
edata = events.dirCurrentEvents(t.strftime("%Y-%m-%d"))
errmess = "" if edata.count <= 10 else "イベントが満杯です"
patic = paticip.Paticip()
rSQL = []
for e in edata.items:
if e["id"] == session["id"]:
eSQL = {}
eSQL["eventid"] = e["key"]
rSQL.append(eSQL)
if rSQL:
rdata = patic.getRequest(rSQL)
else:
rdata = None
return render_template("index.html", id=session["id"],edata=edata,rdata=rdata,errmess=errmess)
return render_template("login.html")
@app.route("/signup", methods=["GET"])
def help():
return render_template("signup.html",id=session["id"])
@app.route("/newevent", methods = ["POST"])
def saveEvent():
# 新規または編集の保存
eventname = request.form.get("eventname")
email = request.form.get("email")
limitdate = request.form.get("limitdate")
comment = request.form.get("comment")
events = event.Event()
limitStr = events.fmtDate(limitdate,"-")
if request.form.get("make"):
if request.form.get("ekey"):
key = request.form.get("ekey")
edataorg = events.getEvent(key)
patic = edataorg.items[0].paticip
events.updateEvent(key, session["id"], eventname, limitStr, comment, email, patic)
return redirect(url_for("top"))
# 新規登録
else:
t = datetime.date.today()
patic = [session["id"]]
events.newEvent(session["id"], eventname, t.strftime("%Y-%m-%d"), limitStr, comment, email, patic)
return redirect(url_for("top"))
else:
return redirect(url_for("top"))
@app.route("/event/<ekey>", methods = ["GET"])
def editEvent(ekey):
# 編集の入り
if "id" in session:
# 編集の読み込み
if ekey:
events = event.Event()
edata = events.getEvent({"key":ekey})
return render_template("event.html", id=session["id"],edata=edata)
else:
return render_template("login.html")
@app.route("/event", methods = ["GET"])
def newEvent():
# 新規の入り
if "id" in session:
t = datetime.date.today()
firstDay = t.strftime("%Y-%m-%d")
defaultLimit = t + datetime.timedelta(days=10)
return render_template("event.html", id=session["id"],firstDay=firstDay,limit=defaultLimit)
else:
return render_template("login.html")
@app.route("/newphoto/<ekey>/<string:photoFlag>", methods = ["GET"])
def newPhoto(ekey,photoFlag):
# 新規の入り
if "id" in session:
if ekey:
events = event.Event()
edata = events.getEvent({"key":ekey})
return render_template("photoadd.html", id=session["id"],ekey=ekey,edata=edata,photoFlag=photoFlag)
else:
return render_template("login.html")
else:
return render_template("login.html")
@app.route("/savephoto", methods = ["POST"])
def savePhoto():
# 写真の保存
if "id" in session:
if request.form.get("regist"):
comments = request.form.get("comments")
photoFlag = request.form.get("photoFlag")
filedata = request.files['file']
f = filedata.filename #実ファイル名
drive = driveFile.DriveFile()
tmpfilename = drive.randStr(10) #temporaryファイル名
request.files['file'].save('/tmp/' + tmpfilename) #一旦/tmp別名で保存する
# length = os.stat('/tmp/'+ tmpfilename).st_size #ファイルサイズを調べる
tmpfile = open('/tmp/'+tmpfilename,'rb') #imageファイルの中身を読み込む
tmpdata = tmpfile.read()
res = drive.putFile( f,tmpdata ) #Driveに保存する
tmpfile.close() #imageファイルを閉じる
exif = drive.get_exif_of_image('/tmp/'+tmpfilename) #exifで撮影日付を取得する
os.remove('/tmp/'+tmpfilename) #imageファイルを消す
ekey = request.form.get("ekey")
photo = photoBase.PhotoBase()
photo.newPhoto(session["id"], ekey, f, False, exif['DateTime'],0,comments)
return redirect(url_for("dirPhotos",ekey=ekey,photoFlag=photoFlag))
else:
return redirect(url_for("top"))
else:
return render_template("login.html")
@app.route("/photos/<ekey>/<string:photoFlag>", methods = ["GET"])
def dirPhotos(ekey,photoFlag):
# イベント一覧の入り
if "id" in session:
if ekey:
events = event.Event()
edata = events.getEvent({"key":ekey})
pdata = events.dirEventPhotos(ekey,photoFlag)
errmess = "" if pdata == None or len(pdata) <= 10 else "写真が満杯です"
return render_template("photos.html", id=session["id"],edata=edata,pdata=pdata,photoFlag=photoFlag,errmess=errmess)
else:
return render_template("login.html")
@app.route("/photo/<ekey>/<pkey>/<filename>", methods = ["GET"])
def deletePhoto(ekey,pkey,filename):
# イベント一覧の入り
if "id" in session:
if pkey:
drives = driveFile.DriveFile()
photos = photoBase.PhotoBase()
events = event.Event()
drives.deleteFile(filename)
photos.deletePhoto(pkey)
edata = events.getEvent({"key":ekey})
pdata = events.dirEventPhotos(ekey,False)
return render_template("photos.html", id=session["id"],edata=edata,pdata=pdata,photoFlag=False)
else:
return render_template("login.html")
@app.route("/request/<ekey>/<id>", methods = ["GET"])
def sendRequest(ekey,id):
# 参加の入り
if "id" in session:
events = event.Event()
edata = events.getEvent({"key":ekey})
return render_template("request.html", id=session["id"],edata=edata)
else:
return render_template("login.html")
@app.route("/request", methods = ["POST"])
def postRequest():
# 参加の保存
if "id" in session:
fromid = request.form.get("fromid")
ekey = request.form.get("key")
eventname = request.form.get("event")
rmemo = request.form.get("rmemo")
events = event.Event()
if request.form.get("request"):
#申請
patic = paticip.Paticip()
result = patic.getRequest({"userid":fromid,"eventid":ekey})
if result.count > 0:
edata = events.getEvent({"key":ekey})
errmess = "申請済みです"
return render_template("request.html", id=session["id"],edata=edata,errmess=errmess)
else:
patic.newRequest(ekey,eventname,fromid,rmemo)
return redirect(url_for("top"))
else:
return render_template("login.html")
@app.route("/patic/<pkey>/<fromid>", methods = ["GET"])
def sendPatic(pkey,fromid):
# 許可の入り
if "id" in session:
patic = paticip.Paticip()
pdata = patic.getRequest({"key":pkey})
return render_template("patic.html", id=session["id"],pdata=pdata)
else:
return render_template("login.html")
@app.route("/patic", methods = ["POST"])
def postPatic():
# 許可の保存
if "id" in session:
fromid = request.form.get("fromid")
pkey = request.form.get("pkey")
ekey = request.form.get("ekey")
patic = paticip.Paticip()
if request.form.get("accept"):
#許可
events = event.Event()
edataorg = events.getEvent({"key":ekey})
paticList = edataorg.items[0]["paticip"]
#許可追加
if not fromid in paticList:
paticList.append(fromid)
events.updateEvent(ekey, session["id"], edataorg.items[0]["eventname"],
edataorg.items[0]["firstDay"], edataorg.items[0]["limitdate"],
edataorg.items[0]["comment"], edataorg.items[0]["email"], paticList)
patic.deleteRequest(pkey)
elif request.form.get("ban"):
patic.deleteRequest(pkey)
return redirect(url_for("top"))
else:
return render_template("login.html")
@app.route("/logout", methods=["GET"])
def logout():
#期限切れ写真の削除
events = event.Event()
photos = photoBase.PhotoBase()
drive = driveFile.DriveFile()
t = datetime.date.today()
edata = events.dirLostEvents(t.strftime("%Y-%m-%d"))
for e in edata.items:
pdata = events.dirEventPhotos(e["key"],True)
if pdata != None:
for p in pdata:
drive.deleteFile(p["filename"])
photos.deletePhoto(p["key"])
events.deleteEvent(e["key"])
session.pop('id',None)
session.clear()
return redirect("/")
if __name__ == '__main__':
app.debug = True
app.run(host='localhost',threaded=True)
ばらばらに掲載したので最後にまとめました
css部分
/static/css/style.css
html,
body {
height: 100%;
}
body {
padding-bottom: 40px;
background-color: #f5f5f5;
}
/*
* Singin
*/
#login-form {
display: flex;
align-items: center;
}
.form-signin {
width: 100%;
max-width: 330px;
padding: 15px;
margin: auto;
}
.form-signin .checkbox {
font-weight: 400;
}
.form-signin .form-floating:focus-within {
z-index: 2;
}
.form-signin input[type="text"] {
margin-bottom: -1px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.form-signin input[type="password"] {
margin-bottom: 10px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
/*
* index
*/
#index-header {
display: inline-flex;
}
.navbar {
margin-bottom: 20px;
}
.event-dir {
background-color: #f1f4f4;
}
.message-dir {
background-color: #f1f4f4;
}
.list-bgcolor {
background-color: rgb(134, 157, 199);
}
特に同じにする必要はありません
環境設定ファイル
requirements.txt
flask deta Pillow flask_bcrypt
この処理で必要なライブラリーです。flask_bcryptがパスワードの暗号化の部分です
Spacefile
# Spacefile Docs: https://go.deta.dev/docs/spacefile/v0
v: 0
micros:
- name: eventphotos
src: ./
engine: python3.9
primary: true
deta.spaceで追加された設定ファイルです
全体のまとめ
まあなんとかできましたが、実用的ではありません。せめて10秒のタイムアウトがなければいいのですが
WEB APIとしてデータを返すパターンが向いていると思います。
とりあえず、私が作ったサンプルを公開しますeventphotos
ユーザーは一度作ると消せないので、パスワード等しっかり管理してください。ただし、いつまで公開するか保証のかぎりではありません。