공부한 내용 정리하는 공간입니다.
틀린 내용이 있을 수 있습니다.
모든 지적, 첨언 환영합니다.
오늘의 코드
1. 특정 폴더의 파일 목록 웹에 표시
2. 사용자가 웹에서 선택한 파일 압축
3. 사용자에게 압축 파일 제공
from flask import Flask, render_template, request, send_file
import os
from datetime import datetime
import zipfile
app = Flask(__name__)
@app.route("/", methods=['GET', 'POST'])
def list():
UPLOAD_PATH = "uploads"
files = []
for file in os.listdir(UPLOAD_PATH):
file_path = os.path.join(UPLOAD_PATH, file)
file_size = os.path.getsize(file_path)
file_ctime = datetime.fromtimestamp(os.path.getctime(file_path)).strftime('%Y-%m-%d %H:%M:%S')
files.append((file, file_size, file_ctime, file_path))
print(files)
return render_template('list.html', files=files)
@app.route("/compress", methods=['GET', 'POST'])
def compress():
UPLOAD_PATH = "uploads"
files = request.form.getlist("files")
zip_path = os.path.join(UPLOAD_PATH, "compress.zip")
with zipfile.ZipFile(zip_path, "w") as zip_file:
for file in files:
file_path = os.path.join(UPLOAD_PATH, file)
zip_file.write(file_path, file)
return send_file(zip_path, as_attachment=True)
if __name__ == '__main__':
app.run(debug=True)
list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test</title>
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename='style.css')}}">
</head>
<body>
<form method="post" action="{{url_for('compress')}}">
<table border="1">
<tr>
<td>파일 이름</td>
<td>파일 크기</td>
<td>파일 수정 날짜</td>
<td>파일 경로</td>
<td>파일 선택</td>
</tr>
{% for file in files %}
<tr>
<td>{{file[0]}}</td>
<td>{{file[1]}}</td>
<td>{{file[2]}}</td>
<td>{{file[3]}}</td>
<td><input type="checkbox" name="files" value="{{file[0]}}"></td>
</tr>
{% endfor %}
</table>
<input type="submit" value="파일 압축하기">
</form>
</body>
</html>
datetime.fromtimestamp(os.path.getctime(파일경로)).strftime('%Y-%m-%d %H:%M:%S')
파일 생성 시간(ctime)을 가져와서 사람이 읽을 수 있는 형식으로 변환
datetime.fromtimestamp : 타임스탬프 값을 python의 datetime 객체로 변환, 사람이 읽을 수 있음
os.path.getctime(파일경로) : '파일 경로'의 생성 시간을 UNIX 타임스탬프 형식으로 반환, 사람이 읽을 수 없음
.strftime('%Y-%m-%d %H:%M:%S') : datetime 객체를 특정 혁식의 문자열로 변환, 사람이 읽을 수 있음
request.form.list()
HTML 폼 데이터를 리스트 형태로 가져올 때 사용
여러 개의 값을 하나로 가져올 때 유용함
zipfile.ZipFile(파일의 온전한 경로, 모드)
ZIP 파일을 생성하거나 읽고, 파일을 추가하거나 추출할 때 사용
with as문으로 사용할 경우 with문이 끝나면 자동으로 파일을 닫음
zipfile.ZipFile 객체.write(파일의 온전한 경로, zip안에서 표시될 이름)
지정된 파일을 ZIP 파일에 추가
ZIP 파일이 쓰기모드로 열려있어야 파일을 추가할 수 있음
'파일의 온전한 경로'는 절대경로일 수 있지만, 'zip안에서 표시될 이름'은 ZIP 내부에 상대경로로 저장
'zip안에서 표시될 이름'은 경로를 포함할 수 있음
오늘의 코드
1. 특정 폴더의 파일 목록 웹에 표시
2. 사용자가 웹에서 선택한 파일 압축
3. 사용자에게 압축 파일 제공
from flask import Flask, render_template, request, send_file
import os
from datetime import datetime
import zipfile
app = Flask(__name__)
@app.route("/", methods=['GET', 'POST'])
def list():
UPLOAD_PATH = "uploads"
files = []
for file in os.listdir(UPLOAD_PATH):
file_path = os.path.join(UPLOAD_PATH, file)
file_size = os.path.getsize(file_path)
file_ctime = datetime.fromtimestamp(os.path.getctime(file_path)).strftime('%Y-%m-%d %H:%M:%S')
files.append((file, file_size, file_ctime, file_path))
print(files)
return render_template('list.html', files=files)
@app.route("/compress", methods=['GET', 'POST'])
def compress():
UPLOAD_PATH = "uploads"
files = request.form.getlist("files")
zip_path = os.path.join(UPLOAD_PATH, "compress.zip")
with zipfile.ZipFile(zip_path, "w") as zip_file:
for file in files:
file_path = os.path.join(UPLOAD_PATH, file)
zip_file.write(file_path, file)
return send_file(zip_path, as_attachment=True)
if __name__ == '__main__':
app.run(debug=True)
list.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>test</title>
<link rel="stylesheet" type="text/css" href="{{url_for('static', filename='style.css')}}">
</head>
<body>
<form method="post" action="{{url_for('compress')}}">
<table border="1">
<tr>
<td>파일 이름</td>
<td>파일 크기</td>
<td>파일 수정 날짜</td>
<td>파일 경로</td>
<td>파일 선택</td>
</tr>
{% for file in files %}
<tr>
<td>{{file[0]}}</td>
<td>{{file[1]}}</td>
<td>{{file[2]}}</td>
<td>{{file[3]}}</td>
<td><input type="checkbox" name="files" value="{{file[0]}}"></td>
</tr>
{% endfor %}
</table>
<input type="submit" value="파일 압축하기">
</form>
</body>
</html>
오늘의 코드 설명
1. 특정 폴더의 파일 목록 웹에 표시
file_ctime = datetime.fromtimestamp(os.path.getctime(file_path)).strftime('%Y-%m-%d %H:%M:%S')
file_path=os.path.join(UPLOAD_PATH, file)=경로 uploads와 uploads에 있는 파일 이름으로 만든 온전한 경로
file_path에 있는 파일의 생성 시간을 file_ctime에 저장
files.append((file, file_size, file_ctime, file_path))
file, file_size, file_ctime, file_path를 하나의 튜플로 묶어서 리스트 files에 저장
2. 사용자가 웹에서 선택한 파일 압축
files = request.form.getlist("files")
name 속성이 files인 form 데이터를 가져와서 리스트 형태로 files에 저장
> name 속성이 files인 form은 list.html에 있는 <input> 태그
>list.html의 <form> 태그는 서버에 있는 이름이 compress인 라우터에 POST 요청을 보냄
zip_path = os.path.join(UPLOAD_PATH, "compress.zip")
UPLOAD_PATH와 compress.zip을 결합하여 하나의 온전한 경로를 zip_path에 저장
>UPLOAD_PATH=uploads
>zip_path=uploads/compress.zip
with zipfile.ZipFile(zip_path, "w") as zip_file:
uploads/compress.zip을 쓰기 모드로 열어서 zip_file에 저장
with 문이 끝나면 zip파일을 자동으로 닫음
for file in files:
file은 list.html의 <input>태그에서 가져온 데이터를 저장한 리스트 files를 순회
file_path = os.path.join(UPLOAD_PATH, file)
리스트에 있는 각 파일 이름(file)과 경로(UPLOAD_PATH)를 조합해서 온전한 경로를 만들어 file_path에 저장
zip_file.write(file_path, file)
file_path에 있는 파일을 원래 파일 이름(file)으로 ZIP 파일에 추가
3. 사용자에게 압축 파일 제공
return send_file(zip_path, as_attachment=True)
uploads/compress.zip 파일을 웹 브라우저에 전송하고 사용자에게 다운로드 자동 진행
list.html
<form method="post" action="{{url_for('compress')}}">
서버에 이름이 compress인 라우터에 post 요청을 보냄
<input type="checkbox" name="files" value="{{file[0]}}">
사용자가 여러 선택 항목 중에서 하나 이상의 항목을 선택할 수 있도록 체크박스를 생성
체크박스가 선택되었을 때 서버로 file[0]의 값을 보냄