diff --git a/akarpov/files/migrations/0022_basefileitem_download_basefileitem_views_filereport.py b/akarpov/files/migrations/0022_basefileitem_download_basefileitem_views_filereport.py new file mode 100644 index 0000000..d560ebd --- /dev/null +++ b/akarpov/files/migrations/0022_basefileitem_download_basefileitem_views_filereport.py @@ -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, + ), + ), + ], + ), + ] diff --git a/akarpov/files/migrations/0023_rename_download_basefileitem_downloads_and_more.py b/akarpov/files/migrations/0023_rename_download_basefileitem_downloads_and_more.py new file mode 100644 index 0000000..267a021 --- /dev/null +++ b/akarpov/files/migrations/0023_rename_download_basefileitem_downloads_and_more.py @@ -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", + ), + ] diff --git a/akarpov/files/models.py b/akarpov/files/models.py index 1bcc61e..7433b41 100644 --- a/akarpov/files/models.py +++ b/akarpov/files/models.py @@ -5,9 +5,11 @@ CASCADE, BooleanField, CharField, + DateTimeField, FileField, ForeignKey, IntegerField, + Model, SlugField, TextField, ) @@ -32,6 +34,9 @@ class BaseFileItem(PolymorphicModel): created = AutoCreatedField("created") modified = AutoLastModifiedField("updated") + views = IntegerField(default=0) + downloads = IntegerField(default=0) + class Meta: ordering = ["-modified"] @@ -118,3 +123,11 @@ class FileInTrash(TimeStampedModel): name = CharField(max_length=200, blank=True) user = ForeignKey("users.User", related_name="trash_files", on_delete=CASCADE) 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}" diff --git a/akarpov/files/tables.py b/akarpov/files/tables.py index c4d9006..d692cce 100644 --- a/akarpov/files/tables.py +++ b/akarpov/files/tables.py @@ -5,9 +5,6 @@ class FileTable(tables.Table): name = tables.columns.Column("name", linkify=True) - time = tables.columns.DateTimeColumn( - format="H:m:s", accessor="modified", verbose_name="Time" - ) folder = tables.columns.Column( linkify=True, accessor="parent", verbose_name="Folder" ) @@ -22,7 +19,8 @@ class Meta: "name", "created", "modified", - "time", + "views", + "downloads", "folder", "private", "file", diff --git a/akarpov/files/urls.py b/akarpov/files/urls.py index 21e357d..8f68ab4 100644 --- a/akarpov/files/urls.py +++ b/akarpov/files/urls.py @@ -1,35 +1,37 @@ from django.urls import path from akarpov.files.views import ( - MyChunkedUploadCompleteView, - MyChunkedUploadView, + ChunkedUploadCompleteView, + ChunkedUploadView, TopFolderView, delete_file_view, + file_report_list, file_table, file_update, files_view, folder_create, folder_view, + report_file, ) app_name = "files" urlpatterns = [ path("", TopFolderView.as_view(), name="main"), path("table/", file_table, name="table"), + path("reports/", file_report_list, name="reports"), path( "api/chunked_upload_complete/", - MyChunkedUploadCompleteView.as_view(), + ChunkedUploadCompleteView.as_view(), name="api_chunked_upload_complete", ), path( "api/chunked_upload_complete/", - MyChunkedUploadCompleteView.as_view(), + ChunkedUploadCompleteView.as_view(), name="api_chunked_upload_complete_folder", ), - path( - "api/chunked_upload/", MyChunkedUploadView.as_view(), name="api_chunked_upload" - ), + path("api/chunked_upload/", ChunkedUploadView.as_view(), name="api_chunked_upload"), path("api/folder/create/", folder_create, name="folder_create"), + path("api/file/report/", report_file, name="file_report"), path("api/folder/create/", folder_create, name="sub_folder_create"), path("", files_view, name="view"), path("/update", file_update, name="update"), diff --git a/akarpov/files/views.py b/akarpov/files/views.py index 995264d..ea85c5e 100644 --- a/akarpov/files/views.py +++ b/akarpov/files/views.py @@ -25,7 +25,7 @@ ) from akarpov.files.filters import FileFilter 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.services.preview import get_base_meta from akarpov.files.tables import FileTable @@ -91,6 +91,9 @@ def get_queryset(self): return BaseFileItem.objects.filter(parent=folder) +folder_view = FileFolderView.as_view() + + class FileUpdateView(LoginRequiredMixin, UpdateView): model = File form_class = FileForm @@ -204,10 +207,7 @@ def get_redirect_url(self, *args, **kwargs): delete_file_view = DeleteFileView.as_view() -folder_view = FileFolderView.as_view() - - -class MyChunkedUploadView(ChunkedUploadView): +class ChunkedUploadView(ChunkedUploadView): model = ChunkedUpload field_name = "the_file" @@ -218,7 +218,7 @@ def check_permissions(self, request): ) -class MyChunkedUploadCompleteView(ChunkedUploadCompleteView): +class ChunkedUploadCompleteView(ChunkedUploadCompleteView): def __init__(self, **kwargs): super().__init__(**kwargs) self.message = {} @@ -286,3 +286,26 @@ def get_queryset(self, **kwargs): 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() diff --git a/akarpov/templates/files/list.html b/akarpov/templates/files/list.html index 4aa8b50..9cd3496 100644 --- a/akarpov/templates/files/list.html +++ b/akarpov/templates/files/list.html @@ -52,10 +52,10 @@ {% endif %} {% endif %} - {% if request.user.is_authenticated and is_folder_owner %} +
{% csrf_token %} diff --git a/akarpov/templates/files/reports.html b/akarpov/templates/files/reports.html new file mode 100644 index 0000000..4d24cd7 --- /dev/null +++ b/akarpov/templates/files/reports.html @@ -0,0 +1,14 @@ +{% extends 'base.html' %} +{% load humanize %} + + diff --git a/akarpov/templates/files/tables.html b/akarpov/templates/files/tables.html index 53504a1..e0be624 100644 --- a/akarpov/templates/files/tables.html +++ b/akarpov/templates/files/tables.html @@ -12,7 +12,7 @@ {% block content %}
diff --git a/akarpov/templates/files/view.html b/akarpov/templates/files/view.html index a288229..2d44c51 100644 --- a/akarpov/templates/files/view.html +++ b/akarpov/templates/files/view.html @@ -56,6 +56,7 @@ {% endif %}

{% endif %} + report file
Download {% if has_perm %}