added file info, file report

This commit is contained in:
Alexander Karpov 2023-04-24 15:26:59 +03:00
parent 6d65e771d7
commit c6153b4eaf
10 changed files with 151 additions and 21 deletions

View File

@ -0,0 +1,57 @@
# Generated by Django 4.2 on 2023-04-24 12:03
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
("files", "0021_folder_amount_folder_private"),
]
operations = [
migrations.AddField(
model_name="basefileitem",
name="download",
field=models.IntegerField(default=0),
),
migrations.AddField(
model_name="basefileitem",
name="views",
field=models.IntegerField(default=0),
),
migrations.CreateModel(
name="FileReport",
fields=[
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
("created", models.DateTimeField(auto_now_add=True)),
(
"file",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="reports",
to="files.file",
),
),
(
"user",
models.ForeignKey(
on_delete=django.db.models.deletion.CASCADE,
related_name="reported_file",
to=settings.AUTH_USER_MODEL,
),
),
],
),
]

View File

@ -0,0 +1,22 @@
# Generated by Django 4.2 on 2023-04-24 12:11
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
("files", "0022_basefileitem_download_basefileitem_views_filereport"),
]
operations = [
migrations.RenameField(
model_name="basefileitem",
old_name="download",
new_name="downloads",
),
migrations.RemoveField(
model_name="filereport",
name="user",
),
]

View File

@ -5,9 +5,11 @@
CASCADE, CASCADE,
BooleanField, BooleanField,
CharField, CharField,
DateTimeField,
FileField, FileField,
ForeignKey, ForeignKey,
IntegerField, IntegerField,
Model,
SlugField, SlugField,
TextField, TextField,
) )
@ -32,6 +34,9 @@ class BaseFileItem(PolymorphicModel):
created = AutoCreatedField("created") created = AutoCreatedField("created")
modified = AutoLastModifiedField("updated") modified = AutoLastModifiedField("updated")
views = IntegerField(default=0)
downloads = IntegerField(default=0)
class Meta: class Meta:
ordering = ["-modified"] ordering = ["-modified"]
@ -118,3 +123,11 @@ class FileInTrash(TimeStampedModel):
name = CharField(max_length=200, blank=True) name = CharField(max_length=200, blank=True)
user = ForeignKey("users.User", related_name="trash_files", on_delete=CASCADE) user = ForeignKey("users.User", related_name="trash_files", on_delete=CASCADE)
file = FileField(blank=False, upload_to=trash_file_upload) file = FileField(blank=False, upload_to=trash_file_upload)
class FileReport(Model):
created = DateTimeField(auto_now_add=True)
file = ForeignKey("files.File", related_name="reports", on_delete=CASCADE)
def __str__(self):
return f"report on {self.file}"

View File

@ -5,9 +5,6 @@
class FileTable(tables.Table): class FileTable(tables.Table):
name = tables.columns.Column("name", linkify=True) name = tables.columns.Column("name", linkify=True)
time = tables.columns.DateTimeColumn(
format="H:m:s", accessor="modified", verbose_name="Time"
)
folder = tables.columns.Column( folder = tables.columns.Column(
linkify=True, accessor="parent", verbose_name="Folder" linkify=True, accessor="parent", verbose_name="Folder"
) )
@ -22,7 +19,8 @@ class Meta:
"name", "name",
"created", "created",
"modified", "modified",
"time", "views",
"downloads",
"folder", "folder",
"private", "private",
"file", "file",

View File

@ -1,35 +1,37 @@
from django.urls import path from django.urls import path
from akarpov.files.views import ( from akarpov.files.views import (
MyChunkedUploadCompleteView, ChunkedUploadCompleteView,
MyChunkedUploadView, ChunkedUploadView,
TopFolderView, TopFolderView,
delete_file_view, delete_file_view,
file_report_list,
file_table, file_table,
file_update, file_update,
files_view, files_view,
folder_create, folder_create,
folder_view, folder_view,
report_file,
) )
app_name = "files" app_name = "files"
urlpatterns = [ urlpatterns = [
path("", TopFolderView.as_view(), name="main"), path("", TopFolderView.as_view(), name="main"),
path("table/", file_table, name="table"), path("table/", file_table, name="table"),
path("reports/", file_report_list, name="reports"),
path( path(
"api/chunked_upload_complete/", "api/chunked_upload_complete/",
MyChunkedUploadCompleteView.as_view(), ChunkedUploadCompleteView.as_view(),
name="api_chunked_upload_complete", name="api_chunked_upload_complete",
), ),
path( path(
"api/chunked_upload_complete/<str:slug>", "api/chunked_upload_complete/<str:slug>",
MyChunkedUploadCompleteView.as_view(), ChunkedUploadCompleteView.as_view(),
name="api_chunked_upload_complete_folder", name="api_chunked_upload_complete_folder",
), ),
path( path("api/chunked_upload/", ChunkedUploadView.as_view(), name="api_chunked_upload"),
"api/chunked_upload/", MyChunkedUploadView.as_view(), name="api_chunked_upload"
),
path("api/folder/create/", folder_create, name="folder_create"), path("api/folder/create/", folder_create, name="folder_create"),
path("api/file/report/<str:slug>", report_file, name="file_report"),
path("api/folder/create/<str:slug>", folder_create, name="sub_folder_create"), path("api/folder/create/<str:slug>", folder_create, name="sub_folder_create"),
path("<str:slug>", files_view, name="view"), path("<str:slug>", files_view, name="view"),
path("<str:slug>/update", file_update, name="update"), path("<str:slug>/update", file_update, name="update"),

View File

@ -25,7 +25,7 @@
) )
from akarpov.files.filters import FileFilter from akarpov.files.filters import FileFilter
from akarpov.files.forms import FileForm, FolderForm from akarpov.files.forms import FileForm, FolderForm
from akarpov.files.models import BaseFileItem, File, Folder from akarpov.files.models import BaseFileItem, File, FileReport, Folder
from akarpov.files.previews import extensions, meta, meta_extensions, previews from akarpov.files.previews import extensions, meta, meta_extensions, previews
from akarpov.files.services.preview import get_base_meta from akarpov.files.services.preview import get_base_meta
from akarpov.files.tables import FileTable from akarpov.files.tables import FileTable
@ -91,6 +91,9 @@ def get_queryset(self):
return BaseFileItem.objects.filter(parent=folder) return BaseFileItem.objects.filter(parent=folder)
folder_view = FileFolderView.as_view()
class FileUpdateView(LoginRequiredMixin, UpdateView): class FileUpdateView(LoginRequiredMixin, UpdateView):
model = File model = File
form_class = FileForm form_class = FileForm
@ -204,10 +207,7 @@ def get_redirect_url(self, *args, **kwargs):
delete_file_view = DeleteFileView.as_view() delete_file_view = DeleteFileView.as_view()
folder_view = FileFolderView.as_view() class ChunkedUploadView(ChunkedUploadView):
class MyChunkedUploadView(ChunkedUploadView):
model = ChunkedUpload model = ChunkedUpload
field_name = "the_file" field_name = "the_file"
@ -218,7 +218,7 @@ def check_permissions(self, request):
) )
class MyChunkedUploadCompleteView(ChunkedUploadCompleteView): class ChunkedUploadCompleteView(ChunkedUploadCompleteView):
def __init__(self, **kwargs): def __init__(self, **kwargs):
super().__init__(**kwargs) super().__init__(**kwargs)
self.message = {} self.message = {}
@ -286,3 +286,26 @@ def get_queryset(self, **kwargs):
file_table = FileTableView.as_view() file_table = FileTableView.as_view()
class ReportFileView(RedirectView):
def get_redirect_url(self, *args, **kwargs):
file = get_object_or_404(File, slug=kwargs["slug"])
FileReport.objects.create(file=file)
return reverse("files:view", kwargs={"slug": file.slug})
report_file = ReportFileView.as_view()
class ListFileReports(LoginRequiredMixin, ListView):
model = FileReport
template_name = "files/reports.html"
def get_queryset(self):
if self.request.user.is_superuser:
return FileReport.objects.all()
return FileReport.objects.none()
file_report_list = ListFileReports.as_view()

View File

@ -52,10 +52,10 @@
</nav> </nav>
{% endif %} {% endif %}
{% endif %} {% endif %}
<div class="d-flex justify-content-end me-5">
<a class="me-5" href="{% url 'files:table' %}">View in table view</a>
</div>
{% if request.user.is_authenticated and is_folder_owner %} {% if request.user.is_authenticated and is_folder_owner %}
<div class="d-flex justify-content-end me-5">
<a class="me-5" href="{% url 'files:table' %}">table view</a>
</div>
<div class="col-lg-2 col-xxl-2 col-md-4 col-sm-6 col-xs-12 mb-3 m-3 d-flex align-items-stretch card"> <div class="col-lg-2 col-xxl-2 col-md-4 col-sm-6 col-xs-12 mb-3 m-3 d-flex align-items-stretch card">
<div class="card-body d-flex flex-column justify-content-center align-items-center"> <div class="card-body d-flex flex-column justify-content-center align-items-center">
{% csrf_token %} {% csrf_token %}

View File

@ -0,0 +1,14 @@
{% extends 'base.html' %}
{% load humanize %}
<div class="list-group">
{% for file in filereport_list %}
<a href="{{ file.file.get_absolute_url }}" class="list-group-item list-group-item-action">
<div class="d-flex w-100 justify-content-between">
<h5 class="mb-1">{{ file.file.name }}</h5>
<small>{{ file.created | naturaltime }}</small>
</div>
<small>{{ file.file.file_type }}</small>
</a>
{% endfor %}
</div>

View File

@ -12,7 +12,7 @@
{% block content %} {% block content %}
<div class="justify-content-end d-flex"> <div class="justify-content-end d-flex">
<a href="{% url 'files:main' %}">View in folder view</a> <a href="{% url 'files:main' %}">folder view</a>
</div> </div>
<form class="mb-4 p-2" > <form class="mb-4 p-2" >
<div class="row d-flex"> <div class="row d-flex">

View File

@ -56,6 +56,7 @@
</button> </button>
{% endif %}</p> {% endif %}</p>
{% endif %} {% endif %}
<a class="text-danger mt-2" style="text-decoration: none" href="{% url 'files:file_report' slug=file.slug %}"><i class="bi bi-flag-fill"></i>report file</a>
<div class="mt-4 text-center justify-content-sm-evenly justify-content-md-start gap-3 align-items-md-start align-items-sm-center d-flex"> <div class="mt-4 text-center justify-content-sm-evenly justify-content-md-start gap-3 align-items-md-start align-items-sm-center d-flex">
<a class="btn btn-success fs-6" href="{{ file.file.url }}" download><i class="bi bi-download"></i> Download</a> <a class="btn btn-success fs-6" href="{{ file.file.url }}" download><i class="bi bi-download"></i> Download</a>
{% if has_perm %} {% if has_perm %}