Skip to content
Snippets Groups Projects
Commit 737198f4 authored by Tomáš Valenta's avatar Tomáš Valenta
Browse files

authenticated file views

parent 2be26a37
Branches
No related tags found
No related merge requests found
Pipeline #13000 passed
from datetime import timedelta
import mimetypes
import uuid
from datetime import datetime, timedelta
from django.contrib.auth.models import Group
from django.core.exceptions import ValidationError
from django.db import models
from django.db.models.fields.files import FieldFile
from django.urls import reverse
from django.utils import timezone
from django.utils.safestring import mark_safe
from markdownx.models import MarkdownxField
from shared.models import NameStrMixin
......@@ -35,7 +41,7 @@ class LectureGroup(NameStrMixin, models.Model):
Group,
blank=True,
verbose_name="Uživatelské skupiny",
help_text="Pokud žádné nedefinuješ, školení ve skupině jsou dostupné všem.",
help_text="Pokud žádné nedefinuješ, školení ve skupině jsou dostupná všem.",
)
class Meta:
......@@ -112,6 +118,7 @@ class LectureLector(NameStrMixin, models.Model):
blank=True,
null=True,
verbose_name="Odkaz",
help_text=mark_safe("Běžně na <a href=\"https://lide.pirati.cz\">aplikaci Lidé</a>.")
)
username = models.CharField(
......@@ -148,6 +155,7 @@ class LectureRecording(NameStrMixin, models.Model):
blank=True,
null=True,
verbose_name="Odkaz",
help_text=mark_safe("Běžně na <a href=\"https://tv.pirati.cz\">Pirátskou TV</a>.")
)
class Meta:
......@@ -155,6 +163,46 @@ class LectureRecording(NameStrMixin, models.Model):
verbose_name_plural = "Nahrávky"
def get_lecture_material_file_location(instance, filename):
mimetypes_instance = mimetypes.MimeTypes()
current_time = datetime.today()
guessed_type = mimetypes_instance.guess_type(filename, strict=False)[0]
extension = ""
if guessed_type is not None:
for mapper in mimetypes_instance.types_map_inv:
if guessed_type not in mapper:
continue
extension = mapper[guessed_type]
if isinstance(extension, list):
extension = extension[0]
break
return (
"_private/"
f"{current_time.year}/{current_time.month}/{current_time.day}/"
f"{uuid.uuid4()}{extension}"
)
class LectureMaterialFileProxy(FieldFile):
@property
def url(self) -> str:
return reverse(
"lectures:download_material_file",
args=(str(self.instance.id),)
)
class LectureMaterialFileField(models.FileField):
attr_class = LectureMaterialFileProxy
class LectureMaterial(NameStrMixin, models.Model):
lecture = models.ForeignKey(
"Lecture",
......@@ -176,13 +224,21 @@ class LectureMaterial(NameStrMixin, models.Model):
help_text="Pokud máš zadaný odkaz, nemůžeš definovat soubor.",
)
file = models.FileField(
file = LectureMaterialFileField(
blank=True,
null=True,
upload_to=get_lecture_material_file_location,
verbose_name="Soubor",
help_text="Pokud máš vložený soubor, nemůžeš definovat odkaz.",
)
@property
def protected_file_url(self) -> str:
return reverse(
"lectures:download_material_file",
args=(self.id,),
)
def clean(self) -> None:
BOTH_FILE_AND_LINK_DEFINED = (
"Definuj prosím pouze odkaz, nebo soubor. Nemůžeš mít oboje najednou."
......
......@@ -9,4 +9,9 @@ urlpatterns = [
"groups/<int:group_id>", views.view_group_lectures, name="view_group_lectures"
),
path("lectures/<int:lecture_id>", views.view_lecture, name="view_lecture"),
path(
"lectures/materials/<str:pk>/file",
views.LectureMaterialFileDownloadView.as_view(),
name="download_material_file",
)
]
# import calendar
# import locale
import json
from datetime import datetime
from itertools import chain
......@@ -8,12 +9,50 @@ from django.db import models
from django.shortcuts import get_object_or_404, render
from django.urls import reverse
from django.utils import timezone
from django_downloadview import ObjectDownloadView
from django_http_exceptions import HTTPExceptions
from guardian.shortcuts import get_objects_for_user
from .models import Lecture, LectureGroup
from .models import Lecture, LectureGroup, LectureMaterial
# import locale
class LectureMaterialFileDownloadView(ObjectDownloadView):
model = LectureMaterial
file_field = "file"
attachment = False
def get_queryset(self, *args, **kwargs):
queryset = (
super()
.get_queryset(*args, **kwargs)
.filter(
lecture__groups__in=(
get_objects_for_user(
self.current_user,
"lectures.view_lecturegroup"
).
filter(
models.Q(user_groups__in=self.current_user.groups.all())
| models.Q(user_groups=None)
)
)
)
)
print(
queryset,
get_objects_for_user(
self.current_user,
"lectures.view_lecturegroup"
)
)
return queryset
def get(self, request, *args, **kwargs):
self.current_user = request.user
return super().get(request, *args, **kwargs)
def get_base_context(request) -> dict:
......
from django.contrib import admin
# Register your models here.
from django.apps import AppConfig
class MediaServerConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "media_server"
from django.db import models
# Create your models here.
from django.test import TestCase
# Create your tests here.
from django.urls import path
from . import views
app_name = "media_server"
urlpatterns = [
path(
"<path:path>",
views.view_media,
name="view_media",
),
]
import os
from django.core.files.storage import FileSystemStorage
from django_downloadview import StorageDownloadView
from django_http_exceptions import HTTPExceptions
# Create your views here.
storage = FileSystemStorage()
class MediaView(StorageDownloadView):
attachment = False
def get_path(self, *args, **kwargs) -> str:
path = super().get_path(*args, **kwargs)
# Make sure path is clean
path = os.path.normpath(path)
if path.startswith("_"): # Private path
raise HTTPExceptions.NOT_FOUND
return path
view_media = MediaView.as_view(storage=storage)
......@@ -3,6 +3,7 @@ django-admin-index==2.0.2
django-admin-interface==0.24.2
django-database-url==1.0.3
django-dbsettings==1.3.0
django-downloadview==2.3.0
django-markdownx==4.0.0b1
django-ordered-model==3.7.1
psycopg2-binary==2.9.5
......
......@@ -57,6 +57,7 @@ INSTALLED_APPS = [
"pirates",
"webpack_loader",
"shared",
"media_server",
"oidc",
"users",
"lectures",
......
......@@ -27,5 +27,6 @@ urlpatterns = [
path("", include("lectures.urls")),
path("markdownx/", include("markdownx.urls")),
path("settings/", include("dbsettings.urls")),
path("media/", include("media_server.urls")),
path("admin/", admin.site.urls),
] + pirates_urlpatterns
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment