Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature/BE-32 : User History #354

Merged
merged 8 commits into from
Dec 18, 2022
2 changes: 1 addition & 1 deletion App/backend/api/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 4.1.2 on 2022-12-09 09:21
# Generated by Django 4.1.2 on 2022-12-10 20:41

from django.conf import settings
import django.contrib.auth.models
Expand Down
3 changes: 2 additions & 1 deletion App/backend/api/models/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ def changeOTP(self, *args, **kwargs):
return code_string

def __str__(self):
return self.name + " " + self.surname
return "User: " + self.name + " " + self.surname


@property
def get_followers(self):
Expand Down
7 changes: 7 additions & 0 deletions App/backend/api/views/artitem.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@


from drf_yasg import openapi
from history.decorators import object_viewed_decorator
from history.signals import object_viewed_signal

# List of routes / method / action:
#
Expand Down Expand Up @@ -248,6 +250,7 @@ def delete_artitem(request, id):
),
}
)
#@object_viewed_decorator()
@api_view(["GET"])
def artitems_by_id(request, id):
if request.method == "GET":
Expand All @@ -256,12 +259,16 @@ def artitems_by_id(request, id):
data = ArtItemSerializer(artitem).data.copy()
if(isinstance(request.user, AnonymousUser)):
data["isLiked"] = False
#print("anonymous")
else:
try:
LikeArtItem.objects.get(user=request.user, artitem=artitem)
data["isLiked"] = True
except:
data["isLiked"] = False
#print("not anonymous")
instance = artitem
object_viewed_signal.send(instance.__class__, instance=instance, request=request)
return Response(data, status=status.HTTP_200_OK)
except ArtItem.DoesNotExist:
return Response({"Not Found": "Any art item with the given ID doesn't exist."}, status=status.HTTP_404_NOT_FOUND)
Expand Down
4 changes: 4 additions & 0 deletions App/backend/api/views/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from ..utils import ProfileImageStorage
from ..models.user import Follow

from history.signals import object_viewed_signal

@ swagger_auto_schema(
method='get',
Expand Down Expand Up @@ -66,6 +67,9 @@ def profile_api(request, id):
data["isFollowed"] = True
except:
data["isFollowed"] = False

instance = user
object_viewed_signal.send(User, instance=instance, request=request)

return Response(data, status=status.HTTP_200_OK)
except User.DoesNotExist:
Expand Down
1 change: 1 addition & 0 deletions App/backend/backend/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
'corsheaders',
'mptt',
'django_extensions',
'history',
]

MIDDLEWARE = [
Expand Down
Empty file added App/backend/history/__init__.py
Empty file.
5 changes: 5 additions & 0 deletions App/backend/history/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.contrib import admin
from .models import History

# Register your models here.
admin.site.register(History)
6 changes: 6 additions & 0 deletions App/backend/history/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class HistoryConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'history'
74 changes: 74 additions & 0 deletions App/backend/history/decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import functools
from django.shortcuts import redirect
from django.http import HttpResponseBadRequest
from .signals import object_viewed_signal
from api.models.artitem import ArtItem

from functools import wraps
from django.contrib import messages
from django.shortcuts import redirect
from django.http import HttpResponse
from django.contrib.auth.models import AnonymousUser

# def object_viewed_decorator(function, request):

# if request.user.is_authenticated:
# # We do not apply the decorator to the function
# return function
# else:
# # We apply the decorator and return the new function
# return newrelic.agent.function_trace()(function)

def bject_viewed_decorator(view_func):
@functools.wraps(view_func)
def wrapper(request, *args, **kwargs):
if request.user.is_authenticated:
try:
instance = view_func.get_object()
except view_func.model.DoesNotExist:
instance = None
object_viewed_signal.send(instance.__class__, instance=instance, request=request)
return view_func(request, *args, **kwargs)
return view_func(request, *args, **kwargs)
return wrapper

def auth_test_function(user):
if user.is_authenticated:
return True
return False

def object_viewed_decorator():
def decorator(view):
@wraps(view)
def _wrapped_view(request, *args, **kwargs):
if(isinstance(request.user, AnonymousUser)):
pass
else:
try:
artitem = ArtItem.objects.get(pk=kwargs["id"])
instance = artitem
object_viewed_signal.send(instance.__class__, instance=instance, request=request)

# instance = view.get_object()
except view.model.DoesNotExist:
instance = None
return view(request, *args, **kwargs)

# if not auth_test_function(request.user):
# print("came 3")
# print(kwargs["id"])
# try:
# artitem = ArtItem.objects.get(pk=kwargs["id"])
# instance = artitem
# object_viewed_signal.send(instance.__class__, instance=instance, request=request)

# # instance = view.get_object()
# except view.model.DoesNotExist:
# instance = None
# #object_viewed_signal.send(instance.__class__, instance=instance, request=request)
# print("came here")
# return view(request, *args, **kwargs)
return view(request, *args, **kwargs)

return _wrapped_view
return decorator
31 changes: 31 additions & 0 deletions App/backend/history/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Generated by Django 4.1.2 on 2022-12-14 20:05

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('contenttypes', '0002_remove_content_type_name'),
]

operations = [
migrations.CreateModel(
name='History',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('object_id', models.PositiveIntegerField()),
('viewed_on', models.DateTimeField(auto_now_add=True)),
('content_type', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='contenttypes.contenttype')),
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
options={
'verbose_name_plural': 'Histories',
},
),
]
Empty file.
31 changes: 31 additions & 0 deletions App/backend/history/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from django.conf import settings

from .signals import object_viewed_signal

User = settings.AUTH_USER_MODEL

class History(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
content_type = models.ForeignKey(ContentType, on_delete=models.SET_NULL, null=True) #ArtItem, UserProfile
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey() #the actual object
viewed_on = models.DateTimeField(auto_now_add=True)

def __str__(self):
return "%s viewed: on %s by %s" %(self.content_object, self.viewed_on, self.user)

class Meta:
verbose_name_plural = "Histories"


def object_viewed_receiver(sender, instance, request, *args, **kwargs):
new_history = History.objects.create(
user = request.user,
content_type = ContentType.objects.get_for_model(sender),
object_id = instance.id,
)

object_viewed_signal.connect(object_viewed_receiver)
4 changes: 4 additions & 0 deletions App/backend/history/signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from django.dispatch import Signal


object_viewed_signal = Signal()
3 changes: 3 additions & 0 deletions App/backend/history/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
3 changes: 3 additions & 0 deletions App/backend/history/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.shortcuts import render

# Create your views here.