Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,7 @@ This is a method to run the project in standalone, based on a local SQLite datab
NAME=rosearch
MEDIA_ROOT=/home/roback/media
MEDIA_URL=media/
# To fill
SECRET_KEY=''
SECRET_KEY='' # To fill
```

The SECRET_KEY variable is used internally by Django to encrypt personal app data (more info in [the official doc](https://docs.djangoproject.com/en/5.1/ref/settings/#std-setting-SECRET_KEY)).
Expand Down
Binary file modified requirements.txt
Binary file not shown.
File renamed without changes.
2 changes: 2 additions & 0 deletions src/auth/serializers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

from .token_serializer import AugmentedTokenObtainPairSerializer
11 changes: 11 additions & 0 deletions src/auth/serializers/token_serializer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

from rest_framework_simplejwt.serializers import TokenObtainPairSerializer


class AugmentedTokenObtainPairSerializer(TokenObtainPairSerializer):

@classmethod
def get_token(cls, user):
token_repr = super().get_token(user)
token_repr['username'] = user.username
return token_repr
12 changes: 10 additions & 2 deletions src/roback/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"""

import os
from datetime import timedelta
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
Expand Down Expand Up @@ -42,9 +43,10 @@
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'rest_framework_simplejwt',
'corsheaders',
'drf_spectacular',
'search_targets',
'drf_spectacular',
]

MIDDLEWARE = [
Expand Down Expand Up @@ -139,7 +141,13 @@
'DEFAULT_PAGINATION_CLASS': 'search_targets.paginations.PaginationWithTotalCount',
'PAGE_SIZE': 20,
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
'TEST_REQUEST_DEFAULT_FORMAT': 'json'
'TEST_REQUEST_DEFAULT_FORMAT': 'json',
'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_simplejwt.authentication.JWTAuthentication',),
}

SIMPLE_JWT = {
"ACCESS_TOKEN_LIFETIME": timedelta(days=1),
"TOKEN_OBTAIN_SERIALIZER": "auth.serializers.AugmentedTokenObtainPairSerializer",
}

# Custom media URL
Expand Down
3 changes: 3 additions & 0 deletions src/roback/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView

from search_targets import views as search_target_views
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
Expand All @@ -33,6 +34,8 @@
path('admin/', admin.site.urls),
path('api-auth/', include('rest_framework.urls')),
path('api/', include(router.urls)),
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
path('api/schema/swagger-ui/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
]
Expand Down
2 changes: 1 addition & 1 deletion src/search_targets/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class SearchTargetAdmin(admin.ModelAdmin):
list_display = ("search_text", "insertion_date", "insertion_time")

class MediaAdmin(admin.ModelAdmin):
list_display = ("search_target", "type", "file", "name")
list_display = ("search_target", "type", "file_path", "name")

class URLAdmin(admin.ModelAdmin):
list_display = ("url",)
Expand Down
18 changes: 18 additions & 0 deletions src/search_targets/migrations/0019_rename_file_media_file_path.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.1.1 on 2024-10-10 13:04

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('search_targets', '0018_alter_searchtarget_insertion_time'),
]

operations = [
migrations.RenameField(
model_name='media',
old_name='file',
new_name='file_path',
),
]
2 changes: 1 addition & 1 deletion src/search_targets/models/media_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,5 @@ class Media(Model):
""" Model for a media (image, video, gif, etc)"""
search_target = ForeignKey(SearchTarget, on_delete=CASCADE, related_name="media")
name = TextField()
file = FileField(upload_to=get_media_path)
file_path = FileField(upload_to=get_media_path)
type = TextField(choices=MediaType.choices, default='')
10 changes: 8 additions & 2 deletions src/search_targets/serializers/media_serializer.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@

from rest_framework.serializers import ModelSerializer
from rest_framework.serializers import ModelSerializer, FilePathField, SerializerMethodField

from search_targets.models import Media


class MediaSerializer(ModelSerializer):
class Meta:
model = Media
fields = '__all__'
fields = (
"id",
"name",
"file_path",
"type",
"search_target",
)
11 changes: 6 additions & 5 deletions src/search_targets/serializers/search_target_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,21 @@
from rest_framework.serializers import ModelSerializer

from search_targets.models import SearchTarget
from search_targets.serializers import MediaSerializer


class SearchTargetSerializer(ModelSerializer):

media = MediaSerializer(many=True, required=False)

class Meta:
model = SearchTarget
fields = [
fields = (
"id",
"search_text",
"insertion_date",
"insertion_time",
"origin",
"original_url",
"media"
]


"media",
)
22 changes: 14 additions & 8 deletions src/search_targets/tests/tests_medias_endpoints.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

from django.contrib.auth.models import User
from django.test.client import MULTIPART_CONTENT, encode_multipart, BOUNDARY
from django.core.exceptions import ObjectDoesNotExist
from django.core.files.base import ContentFile
Expand All @@ -14,14 +15,19 @@ class TestMediasEndpoints(APITestCase):
mocked_date = datetime(2000, 1, 1, 2, 2, 2)
endpoint = "/api/medias/"

def setUp(self) -> None:
self.search_target = SearchTarget.objects.create(search_text="test_search_targets")
@classmethod
def setUpTestData(cls):
cls.user = User.objects.create_user(username='test_user', password='test_pwd', is_staff=True)
cls.search_target = SearchTarget.objects.create(search_text="test_search_targets")

def setUp(self):
self.media = Media.objects.create(
search_target=self.search_target,
name="media_name",
file=ContentFile("test_file", name="test_file"),
file_path=ContentFile("test_file", name="test_file"),
type="IMAGE"
)
self.client.force_authenticate(self.user)

def test_get_all(self):
response = self.client.get(self.endpoint)
Expand All @@ -40,10 +46,10 @@ def test_get(self):

def test_post(self):
input_post_data = {
"name": "media_name2",
"file": ContentFile("test_file2", name="test_file2"),
"type": "VIDEO",
"search_target": self.search_target.id
"name": "media_name2",
"file_path": ContentFile("test_file2", name="test_file2"),
"type": "VIDEO",
"search_target": self.search_target.id
}
response = self.client.post(
self.endpoint,
Expand Down Expand Up @@ -71,7 +77,7 @@ def test_patch(self):
def test_put(self):
input_put_data = {
"name": "media_name2",
"file": ContentFile("test_file2", name="test_file2"),
"file_path": ContentFile("test_file2", name="test_file2"),
"type": "VIDEO",
"search_target": self.search_target.id
}
Expand Down
11 changes: 8 additions & 3 deletions src/search_targets/tests/tests_search_targets_endpoints.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from django.contrib.auth.models import User
from django.test.client import MULTIPART_CONTENT, encode_multipart, BOUNDARY
from django.core.exceptions import ObjectDoesNotExist
from rest_framework.test import APITestCase
Expand All @@ -12,15 +13,20 @@

class TestSearchTargetsEndpoints(APITestCase):

mocked_date = datetime(2000, 1, 1, 2, 2, 2)
endpoint = "/api/search_targets/"
mocked_date = datetime(2000, 1, 1, 2, 2, 2)

@classmethod
def setUpTestData(cls):
cls.user = User.objects.create_user(username='test_user', password='test_pwd', is_staff=True)

@patch("datetime.date", get_date_mocker(mocked_date))
@patch("datetime.datetime", get_datetime_mocker(mocked_date))
def setUp(self) -> None:
def setUp(self):
self.test_search_target = SearchTarget.objects.create(
search_text="test_text",
)
self.client.force_authenticate(self.user)

def test_get_all(self):
response = self.client.get(self.endpoint)
Expand Down Expand Up @@ -70,7 +76,6 @@ def test_put(self):
put_text = "put_test_text"
input_put_data = {
"search_text": put_text,
"media": []
}
response = self.client.put(
f"{self.endpoint}{str(self.test_search_target.id)}/",
Expand Down
6 changes: 5 additions & 1 deletion src/search_targets/views/media_view.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@

from rest_framework.viewsets import ModelViewSet
from rest_framework.permissions import IsAdminUser

from search_targets.models import Media
from search_targets.serializers import MediaSerializer


class MediaAPIView(ModelViewSet):

permission_classes = [IsAdminUser]
serializer_class = MediaSerializer

def get_queryset(self):
return Media.objects.all()
queryset = Media.objects.all()
queryset = queryset.order_by("search_target")
return queryset
4 changes: 3 additions & 1 deletion src/search_targets/views/search_targets_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@

from django.conf import settings
from django.forms import modelformset_factory
from django.http import HttpResponseNotAllowed, JsonResponse, HttpResponseBadRequest
from django.http import HttpResponseNotAllowed, JsonResponse

from rest_framework.viewsets import ModelViewSet
from rest_framework.parsers import MultiPartParser
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response

from search_targets.models import Media, MediaType, SearchTarget, URL
Expand All @@ -27,6 +28,7 @@ def extract_url_from_text(text: str) -> List[str]:

class SearchTargetAPIView(ModelViewSet):

permission_classes = [IsAuthenticated]
pagination_class = PaginationWithTotalCount
serializer_class = SearchTargetSerializer
parser_classes = [MultiPartParser]
Expand Down
Empty file removed tests/test_search_targets.py
Empty file.
Loading