aboutsummaryrefslogtreecommitdiff
path: root/uploader/files/functions.py
diff options
context:
space:
mode:
Diffstat (limited to 'uploader/files/functions.py')
-rw-r--r--uploader/files/functions.py39
1 files changed, 39 insertions, 0 deletions
diff --git a/uploader/files/functions.py b/uploader/files/functions.py
new file mode 100644
index 0000000..5a3dece
--- /dev/null
+++ b/uploader/files/functions.py
@@ -0,0 +1,39 @@
+"""Utilities to deal with uploaded files."""
+import hashlib
+from pathlib import Path
+from datetime import datetime
+
+from flask import current_app
+
+from werkzeug.utils import secure_filename
+from werkzeug.datastructures import FileStorage
+
+from .chunks import chunked_binary_read
+
+def save_file(fileobj: FileStorage, upload_dir: Path) -> Path:
+ """Save the uploaded file and return the path."""
+ assert bool(fileobj), "Invalid file object!"
+ hashed_name = hashlib.sha512(
+ f"{fileobj.filename}::{datetime.now().isoformat()}".encode("utf8")
+ ).hexdigest()
+ filename = Path(secure_filename(hashed_name)) # type: ignore[arg-type]
+ if not upload_dir.exists():
+ upload_dir.mkdir()
+
+ filepath = Path(upload_dir, filename)
+ fileobj.save(filepath)
+ return filepath
+
+
+def fullpath(filename: str):
+ """Get a file's full path. This makes use of `flask.current_app`."""
+ return Path(current_app.config["UPLOAD_FOLDER"], filename).absolute()
+
+
+def sha256_digest_over_file(filepath: Path) -> str:
+ """Compute the sha256 digest over a file's contents."""
+ filehash = hashlib.sha256()
+ for chunk in chunked_binary_read(filepath):
+ filehash.update(chunk)
+
+ return filehash.hexdigest()