Even more style fixes :)
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
c6d7566c72
commit
cc46df81fe
|
|
@ -2,5 +2,5 @@ from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
class CommonConfig(AppConfig):
|
class CommonConfig(AppConfig):
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
default_auto_field = "django.db.models.BigAutoField"
|
||||||
name = 'common'
|
name = "common"
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ class UPLOAD_ERROR_CODES:
|
||||||
FILE_MISSING = "file_missing"
|
FILE_MISSING = "file_missing"
|
||||||
CHUNK_MISMATCH = "chunk_mismatch"
|
CHUNK_MISMATCH = "chunk_mismatch"
|
||||||
|
|
||||||
|
|
||||||
# Config
|
# Config
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
from django.urls import path
|
|
||||||
|
|
||||||
from common import views_api
|
from common import views_api
|
||||||
|
from django.urls import path
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("api/configs/", views_api.configs, name="api-config"),
|
path("api/configs/", views_api.configs, name="api-config"),
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,7 @@ def cast_to_native_type(key, value, native_type):
|
||||||
try:
|
try:
|
||||||
return native_type(value)
|
return native_type(value)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
message = (
|
message = f"Received unexpected value type for configuration key {key}\nValue: {value}\nExpected type : {native_type}"
|
||||||
f"Received unexpected value type for configuration key {key}\nValue: {value}\nExpected type : {native_type}"
|
|
||||||
)
|
|
||||||
raise ValueError(message) from e
|
raise ValueError(message) from e
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,6 @@ import os
|
||||||
|
|
||||||
from django.core.asgi import get_asgi_application
|
from django.core.asgi import get_asgi_application
|
||||||
|
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'lockbox.settings')
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lockbox.settings")
|
||||||
|
|
||||||
application = get_asgi_application()
|
application = get_asgi_application()
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
"""Lockbox File Sharing"""
|
"""Lockbox File Sharing"""
|
||||||
|
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from common.utils import get_config
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
from lockbox.setup import validate_paths
|
from lockbox.setup import validate_paths
|
||||||
from common.utils import get_config
|
|
||||||
|
|
||||||
|
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
|
|
@ -55,48 +54,48 @@ MIDDLEWARE = [
|
||||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'lockbox.urls'
|
ROOT_URLCONF = "lockbox.urls"
|
||||||
|
|
||||||
TEMPLATES = [
|
TEMPLATES = [
|
||||||
{
|
{
|
||||||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||||
'DIRS': [BASE_DIR / "templates"],
|
"DIRS": [BASE_DIR / "templates"],
|
||||||
'APP_DIRS': True,
|
"APP_DIRS": True,
|
||||||
'OPTIONS': {
|
"OPTIONS": {
|
||||||
'context_processors': [
|
"context_processors": [
|
||||||
'django.template.context_processors.debug',
|
"django.template.context_processors.debug",
|
||||||
'django.template.context_processors.request',
|
"django.template.context_processors.request",
|
||||||
'django.contrib.auth.context_processors.auth',
|
"django.contrib.auth.context_processors.auth",
|
||||||
'django.contrib.messages.context_processors.messages',
|
"django.contrib.messages.context_processors.messages",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
WSGI_APPLICATION = 'lockbox.wsgi.application'
|
WSGI_APPLICATION = "lockbox.wsgi.application"
|
||||||
|
|
||||||
# Password validation
|
# Password validation
|
||||||
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
|
# https://docs.djangoproject.com/en/4.2/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
AUTH_PASSWORD_VALIDATORS = [
|
AUTH_PASSWORD_VALIDATORS = [
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
# Internationalization
|
# Internationalization
|
||||||
LANGUAGE_CODE = 'en-us'
|
LANGUAGE_CODE = "en-us"
|
||||||
TIME_ZONE = 'UTC'
|
TIME_ZONE = "UTC"
|
||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
@ -107,7 +106,7 @@ STATICFILES_DIRS = [
|
||||||
BASE_DIR / "static",
|
BASE_DIR / "static",
|
||||||
]
|
]
|
||||||
STATIC_ROOT = BASE_DIR / "staticfiles"
|
STATIC_ROOT = BASE_DIR / "staticfiles"
|
||||||
STATIC_URL = 'static/'
|
STATIC_URL = "static/"
|
||||||
STORAGES = {
|
STORAGES = {
|
||||||
"default": {
|
"default": {
|
||||||
"BACKEND": "django.core.files.storage.FileSystemStorage",
|
"BACKEND": "django.core.files.storage.FileSystemStorage",
|
||||||
|
|
@ -125,11 +124,11 @@ INCOMPLETE_EXT = ".incomplete"
|
||||||
validate_paths(MEDIA_ROOT)
|
validate_paths(MEDIA_ROOT)
|
||||||
|
|
||||||
# Default primary key field type
|
# Default primary key field type
|
||||||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
||||||
AUTH_USER_MODEL = 'user.LockboxUser'
|
AUTH_USER_MODEL = "user.LockboxUser"
|
||||||
|
|
||||||
|
|
||||||
REST_FRAMEWORK = {
|
REST_FRAMEWORK = {
|
||||||
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
|
"DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.LimitOffsetPagination",
|
||||||
'PAGE_SIZE': 50
|
"PAGE_SIZE": 50,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,6 @@ urlpatterns = [
|
||||||
|
|
||||||
|
|
||||||
if get_config("ENABLE_BROWSABLE_API"):
|
if get_config("ENABLE_BROWSABLE_API"):
|
||||||
urlpatterns.extend(path('api-auth/', include('rest_framework.urls')))
|
urlpatterns.extend(path("api-auth/", include("rest_framework.urls")))
|
||||||
|
|
||||||
urlpatterns.extend(static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT))
|
urlpatterns.extend(static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT))
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,6 @@ import os
|
||||||
|
|
||||||
from django.core.wsgi import get_wsgi_application
|
from django.core.wsgi import get_wsgi_application
|
||||||
|
|
||||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'lockbox.settings')
|
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "lockbox.settings")
|
||||||
|
|
||||||
application = get_wsgi_application()
|
application = get_wsgi_application()
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@ from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
class StorageConfig(AppConfig):
|
class StorageConfig(AppConfig):
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
default_auto_field = "django.db.models.BigAutoField"
|
||||||
name = 'storage'
|
name = "storage"
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ class File(LockboxBase):
|
||||||
blank=True,
|
blank=True,
|
||||||
verbose_name=_("file"),
|
verbose_name=_("file"),
|
||||||
help_text=_("actual file"),
|
help_text=_("actual file"),
|
||||||
upload_to=upload_to_fielpath
|
upload_to=upload_to_fielpath,
|
||||||
)
|
)
|
||||||
|
|
||||||
UPLOAD_CHOICES = (
|
UPLOAD_CHOICES = (
|
||||||
|
|
@ -148,11 +148,16 @@ class File(LockboxBase):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def abandoned(self):
|
def abandoned(self):
|
||||||
return self.date_created <= timezone.now() + timedelta(minutes=get_config("ABANDONED_DELTA_MINUTES"))
|
return self.date_created <= timezone.now() + timedelta(
|
||||||
|
minutes=get_config("ABANDONED_DELTA_MINUTES")
|
||||||
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def abandoned_condition():
|
def abandoned_condition():
|
||||||
return models.Q(date_created__lte=timezone.now() + timedelta(minutes=get_config("ABANDONED_DELTA_MINUTES")))
|
return models.Q(
|
||||||
|
date_created__lte=timezone.now()
|
||||||
|
+ timedelta(minutes=get_config("ABANDONED_DELTA_MINUTES"))
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def expired(self):
|
def expired(self):
|
||||||
|
|
@ -179,11 +184,16 @@ class File(LockboxBase):
|
||||||
if chunk_data["start_bytes"] != 0:
|
if chunk_data["start_bytes"] != 0:
|
||||||
self.status = UPLOAD_STATUS_TYPES.ERROR
|
self.status = UPLOAD_STATUS_TYPES.ERROR
|
||||||
self.save()
|
self.save()
|
||||||
raise UploadError("File for uploaded chunk no longer exists", code=UPLOAD_ERROR_CODES.FILE_MISSING)
|
raise UploadError(
|
||||||
|
"File for uploaded chunk no longer exists",
|
||||||
|
code=UPLOAD_ERROR_CODES.FILE_MISSING,
|
||||||
|
)
|
||||||
|
|
||||||
if self.last_end_bytes and self.last_end_bytes + 1 != chunk_data["start_bytes"]:
|
if self.last_end_bytes and self.last_end_bytes + 1 != chunk_data["start_bytes"]:
|
||||||
# Client screwed up, this is not where we left
|
# Client screwed up, this is not where we left
|
||||||
raise UploadError("Mismatch in expected chunk", code=UPLOAD_ERROR_CODES.CHUNK_MISMATCH)
|
raise UploadError(
|
||||||
|
"Mismatch in expected chunk", code=UPLOAD_ERROR_CODES.CHUNK_MISMATCH
|
||||||
|
)
|
||||||
|
|
||||||
self.last_end_bytes = chunk_data["end_bytes"]
|
self.last_end_bytes = chunk_data["end_bytes"]
|
||||||
if self.expected_size == self.last_end_bytes:
|
if self.expected_size == self.last_end_bytes:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from storage.models import File
|
from storage.models import File
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ from rest_framework.routers import SimpleRouter
|
||||||
from storage import views_api, views_client
|
from storage import views_api, views_client
|
||||||
|
|
||||||
router = SimpleRouter()
|
router = SimpleRouter()
|
||||||
router.register(r'files', views_api.FileModelViewSet)
|
router.register(r"files", views_api.FileModelViewSet)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path("api/", include(router.urls)),
|
path("api/", include(router.urls)),
|
||||||
|
|
|
||||||
|
|
@ -27,14 +27,13 @@ class FileModelViewSet(ModelViewSet):
|
||||||
|
|
||||||
chunk_data = self.get_content_range(request)
|
chunk_data = self.get_content_range(request)
|
||||||
if not chunk_data:
|
if not chunk_data:
|
||||||
raise UserValidationError(
|
raise UserValidationError("Missing content-range headers")
|
||||||
"Missing content-range headers"
|
|
||||||
)
|
|
||||||
|
|
||||||
chunk_file = request.FILES["Content"]
|
chunk_file = request.FILES["Content"]
|
||||||
if chunk_file.size > file.max_size_chunk_bytes:
|
if chunk_file.size > file.max_size_chunk_bytes:
|
||||||
raise UserValidationError(
|
raise UserValidationError(
|
||||||
f"Chunk size is greater than files max chunk size: {chunk_file.size} > {file.max_size_chunk_bytes}")
|
f"Chunk size is greater than files max chunk size: {chunk_file.size} > {file.max_size_chunk_bytes}"
|
||||||
|
)
|
||||||
|
|
||||||
range_size = chunk_data["end_bytes"] - chunk_data["start_bytes"]
|
range_size = chunk_data["end_bytes"] - chunk_data["start_bytes"]
|
||||||
if chunk_file.size != range_size:
|
if chunk_file.size != range_size:
|
||||||
|
|
@ -59,6 +58,6 @@ class FileModelViewSet(ModelViewSet):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"start_bytes": int(match.group('start')),
|
"start_bytes": int(match.group("start")),
|
||||||
"end_bytes": int(match.group('end')),
|
"end_bytes": int(match.group("end")),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,5 +2,5 @@ from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
class UserConfig(AppConfig):
|
class UserConfig(AppConfig):
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
default_auto_field = "django.db.models.BigAutoField"
|
||||||
name = 'user'
|
name = "user"
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ from common.models import LockboxBase
|
||||||
from django.contrib.auth.models import AbstractUser
|
from django.contrib.auth.models import AbstractUser
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from user.managers import LockboxUserManager
|
from user.managers import LockboxUserManager
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ class TestUser:
|
||||||
"""
|
"""
|
||||||
Test user related functions are working correctly.
|
Test user related functions are working correctly.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_stub(self):
|
def test_stub(self):
|
||||||
user = LockboxUser.objects.create(alias="TestUser", username="meow")
|
user = LockboxUser.objects.create(alias="TestUser", username="meow")
|
||||||
loaded_user = LockboxUser.objects.filter(alias="TestUser").first()
|
loaded_user = LockboxUser.objects.filter(alias="TestUser").first()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue