mirror of
https://github.com/Alexander-D-Karpov/akarpov
synced 2024-11-29 00:53:42 +03:00
fixed chunked upload
This commit is contained in:
parent
438e978930
commit
88fb87ebae
|
@ -0,0 +1,22 @@
|
||||||
|
# Generated by Django 4.2 on 2023-04-06 10:14
|
||||||
|
|
||||||
|
import akarpov.contrib.chunked_upload.settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("chunked_upload", "0001_initial"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name="chunkedupload",
|
||||||
|
name="file",
|
||||||
|
field=models.FileField(
|
||||||
|
max_length=255,
|
||||||
|
upload_to=akarpov.contrib.chunked_upload.settings.default_upload_to,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -6,8 +6,6 @@
|
||||||
from django.core.serializers.json import DjangoJSONEncoder
|
from django.core.serializers.json import DjangoJSONEncoder
|
||||||
from django.utils.module_loading import import_string
|
from django.utils.module_loading import import_string
|
||||||
|
|
||||||
from akarpov.utils.files import user_file_upload_mixin
|
|
||||||
|
|
||||||
# How long after creation the upload will expire
|
# How long after creation the upload will expire
|
||||||
DEFAULT_EXPIRATION_DELTA = timedelta(days=1)
|
DEFAULT_EXPIRATION_DELTA = timedelta(days=1)
|
||||||
EXPIRATION_DELTA = getattr(
|
EXPIRATION_DELTA = getattr(
|
||||||
|
@ -25,7 +23,7 @@ def default_upload_to(instance, filename):
|
||||||
return time.strftime(filename)
|
return time.strftime(filename)
|
||||||
|
|
||||||
|
|
||||||
UPLOAD_TO = user_file_upload_mixin
|
UPLOAD_TO = default_upload_to
|
||||||
|
|
||||||
# Storage system
|
# Storage system
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.views.generic import View
|
from django.views.generic import View
|
||||||
|
|
||||||
|
from ...utils.generators import generate_charset
|
||||||
from .constants import COMPLETE, http_status
|
from .constants import COMPLETE, http_status
|
||||||
from .exceptions import ChunkedUploadError
|
from .exceptions import ChunkedUploadError
|
||||||
from .models import ChunkedUpload
|
from .models import ChunkedUpload
|
||||||
|
@ -154,7 +155,9 @@ def create_chunked_upload(self, save=False, **attrs):
|
||||||
"""
|
"""
|
||||||
chunked_upload = self.model(**attrs)
|
chunked_upload = self.model(**attrs)
|
||||||
# file starts empty
|
# file starts empty
|
||||||
chunked_upload.file.save(name="", content=ContentFile(""), save=save)
|
chunked_upload.file.save(
|
||||||
|
name=generate_charset(10), content=ContentFile(""), save=save
|
||||||
|
)
|
||||||
return chunked_upload
|
return chunked_upload
|
||||||
|
|
||||||
def is_valid_chunked_upload(self, chunked_upload):
|
def is_valid_chunked_upload(self, chunked_upload):
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
# Generated by Django 4.2 on 2023-04-06 10:14
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("files", "0008_file_completed_on_file_created_on_file_filename_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="file",
|
||||||
|
name="completed_on",
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="file",
|
||||||
|
name="created_on",
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="file",
|
||||||
|
name="filename",
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="file",
|
||||||
|
name="offset",
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="file",
|
||||||
|
name="status",
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name="file",
|
||||||
|
name="upload_id",
|
||||||
|
),
|
||||||
|
]
|
60
akarpov/files/migrations/0010_fileintrash.py
Normal file
60
akarpov/files/migrations/0010_fileintrash.py
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
# Generated by Django 4.2 on 2023-04-06 10:25
|
||||||
|
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
import model_utils.fields
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
("files", "0009_remove_file_completed_on_remove_file_created_on_and_more"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name="FileInTrash",
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
"id",
|
||||||
|
models.BigAutoField(
|
||||||
|
auto_created=True,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
verbose_name="ID",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"created",
|
||||||
|
model_utils.fields.AutoCreatedField(
|
||||||
|
default=django.utils.timezone.now,
|
||||||
|
editable=False,
|
||||||
|
verbose_name="created",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"modified",
|
||||||
|
model_utils.fields.AutoLastModifiedField(
|
||||||
|
default=django.utils.timezone.now,
|
||||||
|
editable=False,
|
||||||
|
verbose_name="modified",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
("file", models.FileField(upload_to="file/trash/")),
|
||||||
|
(
|
||||||
|
"user",
|
||||||
|
models.ForeignKey(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
related_name="trash_files",
|
||||||
|
to=settings.AUTH_USER_MODEL,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
"abstract": False,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
|
@ -10,12 +10,11 @@
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from model_utils.models import TimeStampedModel
|
from model_utils.models import TimeStampedModel
|
||||||
|
|
||||||
from akarpov.contrib.chunked_upload.models import AbstractChunkedUpload
|
|
||||||
from akarpov.tools.shortener.models import ShortLink
|
from akarpov.tools.shortener.models import ShortLink
|
||||||
from akarpov.utils.files import user_file_upload_mixin
|
from akarpov.utils.files import user_file_upload_mixin
|
||||||
|
|
||||||
|
|
||||||
class File(AbstractChunkedUpload, TimeStampedModel, ShortLink):
|
class File(TimeStampedModel, ShortLink):
|
||||||
"""model to store user's files"""
|
"""model to store user's files"""
|
||||||
|
|
||||||
name = CharField(max_length=100)
|
name = CharField(max_length=100)
|
||||||
|
@ -38,6 +37,11 @@ def __str__(self):
|
||||||
return f"file: {self.name}"
|
return f"file: {self.name}"
|
||||||
|
|
||||||
|
|
||||||
|
class FileInTrash(TimeStampedModel):
|
||||||
|
user = ForeignKey("users.User", related_name="trash_files", on_delete=CASCADE)
|
||||||
|
file = FileField(blank=False, upload_to="file/trash/")
|
||||||
|
|
||||||
|
|
||||||
class Folder(TimeStampedModel, ShortLink):
|
class Folder(TimeStampedModel, ShortLink):
|
||||||
name = CharField(max_length=100)
|
name = CharField(max_length=100)
|
||||||
slug = SlugField(max_length=20, blank=True)
|
slug = SlugField(max_length=20, blank=True)
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
|
import os
|
||||||
|
|
||||||
from django.views.generic import DetailView
|
from django.views.generic import DetailView
|
||||||
from django.views.generic.base import TemplateView
|
from django.views.generic.base import TemplateView
|
||||||
|
|
||||||
|
from akarpov.contrib.chunked_upload.exceptions import ChunkedUploadError
|
||||||
|
from akarpov.contrib.chunked_upload.models import ChunkedUpload
|
||||||
from akarpov.contrib.chunked_upload.views import (
|
from akarpov.contrib.chunked_upload.views import (
|
||||||
ChunkedUploadCompleteView,
|
ChunkedUploadCompleteView,
|
||||||
ChunkedUploadView,
|
ChunkedUploadView,
|
||||||
|
@ -31,28 +35,29 @@ class ChunkedUploadDemo(TemplateView):
|
||||||
|
|
||||||
|
|
||||||
class MyChunkedUploadView(ChunkedUploadView):
|
class MyChunkedUploadView(ChunkedUploadView):
|
||||||
model = File
|
model = ChunkedUpload
|
||||||
field_name = "the_file"
|
field_name = "the_file"
|
||||||
|
|
||||||
def check_permissions(self, request):
|
def check_permissions(self, request):
|
||||||
# Allow non authenticated users to make uploads
|
if not self.request.user.is_authenticated:
|
||||||
pass
|
raise ChunkedUploadError(
|
||||||
|
403, message="you are not allowed to access this page"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class MyChunkedUploadCompleteView(ChunkedUploadCompleteView):
|
class MyChunkedUploadCompleteView(ChunkedUploadCompleteView):
|
||||||
model = File
|
model = ChunkedUpload
|
||||||
|
|
||||||
def check_permissions(self, request):
|
def check_permissions(self, request):
|
||||||
# Allow non authenticated users to make uploads
|
if not self.request.user.is_authenticated:
|
||||||
pass
|
raise ChunkedUploadError(
|
||||||
|
403, message="you are not allowed to access this page"
|
||||||
|
)
|
||||||
|
|
||||||
def on_completion(self, uploaded_file, request):
|
def on_completion(self, uploaded_file, request):
|
||||||
# Do something with the uploaded file. E.g.:
|
File.objects.create(user=request.user, file=uploaded_file)
|
||||||
# * Store the uploaded file on another model:
|
if os.path.isfile(uploaded_file.file.path):
|
||||||
# SomeModel.objects.create(user=request.user, file=uploaded_file)
|
os.remove(uploaded_file.file.path)
|
||||||
# * Pass it as an argument to a function:
|
|
||||||
# function_that_process_file(uploaded_file)
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_response_data(self, chunked_upload, request):
|
def get_response_data(self, chunked_upload, request):
|
||||||
return {
|
return {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user