add very basic tag support on upload
This commit is contained in:
parent
e2217fbc1d
commit
3f88cc00b5
4 changed files with 65 additions and 18 deletions
16
poetry.lock
generated
16
poetry.lock
generated
|
@ -232,14 +232,14 @@ tests = ["dj-database-url", "dj-email-url", "django-cache-url", "pytest"]
|
|||
|
||||
[[package]]
|
||||
name = "flask"
|
||||
version = "2.3.3"
|
||||
version = "3.0.0"
|
||||
description = "A simple framework for building complex web applications."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "flask-2.3.3-py3-none-any.whl", hash = "sha256:f69fcd559dc907ed196ab9df0e48471709175e696d6e698dd4dbe940f96ce66b"},
|
||||
{file = "flask-2.3.3.tar.gz", hash = "sha256:09c347a92aa7ff4a8e7f3206795f30d826654baf38b873d0744cd571ca609efc"},
|
||||
{file = "flask-3.0.0-py3-none-any.whl", hash = "sha256:21128f47e4e3b9d597a3e8521a329bf56909b690fcc3fa3e477725aa81367638"},
|
||||
{file = "flask-3.0.0.tar.gz", hash = "sha256:cfadcdb638b609361d29ec22360d6070a77d7463dcb3ab08d2c2f2f168845f58"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -247,7 +247,7 @@ blinker = ">=1.6.2"
|
|||
click = ">=8.1.3"
|
||||
itsdangerous = ">=2.1.2"
|
||||
Jinja2 = ">=3.1.2"
|
||||
Werkzeug = ">=2.3.7"
|
||||
Werkzeug = ">=3.0.0"
|
||||
|
||||
[package.extras]
|
||||
async = ["asgiref (>=3.2)"]
|
||||
|
@ -515,14 +515,14 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "werkzeug"
|
||||
version = "2.3.7"
|
||||
version = "3.0.0"
|
||||
description = "The comprehensive WSGI web application library."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "werkzeug-2.3.7-py3-none-any.whl", hash = "sha256:effc12dba7f3bd72e605ce49807bbe692bd729c3bb122a3b91747a6ae77df528"},
|
||||
{file = "werkzeug-2.3.7.tar.gz", hash = "sha256:2b8c0e447b4b9dbcc85dd97b6eeb4dcbaf6c8b6c3be0bd654e25553e0a2157d8"},
|
||||
{file = "werkzeug-3.0.0-py3-none-any.whl", hash = "sha256:cbb2600f7eabe51dbc0502f58be0b3e1b96b893b05695ea2b35b43d4de2d9962"},
|
||||
{file = "werkzeug-3.0.0.tar.gz", hash = "sha256:3ffff4dcc32db52ef3cc94dff3000a3c2846890f3a5a51800a27b909c5e770f0"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
|
@ -534,4 +534,4 @@ watchdog = ["watchdog (>=2.3)"]
|
|||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.11"
|
||||
content-hash = "a8a740d71fe53f39a3e5d8ff069560abfb1e99db162b77892eb16cd0b34bda9d"
|
||||
content-hash = "f0bb5dc5c2086b3834b9e7c46313f161aa0dab256d158209eb616101c4010d69"
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from flask import Blueprint, g, request, jsonify
|
||||
from werkzeug.utils import secure_filename
|
||||
|
||||
from pyles.db import File
|
||||
from pyles.db import db, File, Tag, FileTag
|
||||
from pyles.files import upload_file
|
||||
from pyles.user import token_required
|
||||
from pyles.settings import BASE_URL
|
||||
|
@ -11,25 +13,49 @@ from pyles.settings import BASE_URL
|
|||
bp = Blueprint("files_api", __name__)
|
||||
|
||||
|
||||
@bp.post("/upload")
|
||||
@bp.post("/api/upload")
|
||||
@token_required
|
||||
def upload():
|
||||
file = request.files.get("file")
|
||||
if not file:
|
||||
return jsonify({"error": "Missing file"}), 400
|
||||
expires = None
|
||||
tags = []
|
||||
try:
|
||||
exp = request.args.get("expires", type=int)
|
||||
expires = datetime.fromtimestamp(exp) if exp else None
|
||||
except:
|
||||
pass
|
||||
|
||||
if raw_tags := request.args.get("tags"):
|
||||
tags = [int(raw) for raw in raw_tags.split(",")]
|
||||
tags: list[Tag] = Tag.select().where(Tag.id.in_(tags), Tag.user_id == g.user.id)
|
||||
|
||||
hash, content_type = upload_file(file)
|
||||
db_file: File = File.create(
|
||||
user=g.user,
|
||||
filename=secure_filename(file.filename),
|
||||
hash=hash,
|
||||
content_type=content_type,
|
||||
)
|
||||
|
||||
with db.atomic():
|
||||
db_file: File = File.create(
|
||||
user=g.user,
|
||||
filename=secure_filename(file.filename),
|
||||
hash=hash,
|
||||
content_type=content_type,
|
||||
expires=expires,
|
||||
)
|
||||
|
||||
if len(tags) > 0:
|
||||
FileTag.bulk_create(FileTag(file=db_file, tag=tag) for tag in tags)
|
||||
|
||||
return jsonify(
|
||||
{
|
||||
"id": db_file.id,
|
||||
"hash": db_file.hash,
|
||||
"url": f"{BASE_URL}/{db_file.path}",
|
||||
"tags": [{"id": tag.id, "name": tag.name} for tag in tags],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@bp.patch("/api/files/<url_id>")
|
||||
@token_required
|
||||
def update_file():
|
||||
...
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
from functools import wraps
|
||||
|
||||
from itsdangerous.url_safe import URLSafeSerializer
|
||||
from flask import g, request, redirect, url_for, jsonify
|
||||
from flask import g, request, redirect, url_for, jsonify, session
|
||||
|
||||
from pyles.settings import SECRET_KEY
|
||||
from pyles.db import User
|
||||
|
@ -27,3 +27,24 @@ def token_required(f):
|
|||
return f(*args, **kwargs)
|
||||
|
||||
return inner
|
||||
|
||||
def login_required(f):
|
||||
@wraps(f)
|
||||
def inner(*args, **kwargs):
|
||||
token = session.get("token", None)
|
||||
if not token:
|
||||
return redirect(url_for("index"))
|
||||
|
||||
_, id = URLSafeSerializer(SECRET_KEY).loads_unsafe(token)
|
||||
u: User = User.get_or_none(id=id)
|
||||
if u is None:
|
||||
session.pop("token", None)
|
||||
return redirect(url_for("index"))
|
||||
|
||||
if not u.verify_token(token):
|
||||
session.pop("token", None)
|
||||
return redirect(url_for("index"))
|
||||
g.user = u
|
||||
return f(*args, **kwargs)
|
||||
|
||||
return inner
|
||||
|
|
|
@ -8,7 +8,7 @@ readme = "README.md"
|
|||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.11"
|
||||
flask = "^2.3.3"
|
||||
flask = "^3.0.0"
|
||||
itsdangerous = "^2.1.2"
|
||||
environs = "^9.5.0"
|
||||
gunicorn = "^21.2.0"
|
||||
|
|
Loading…
Reference in a new issue