Skip to content
New issue

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

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

Already on GitHub? # to your account

Activitylog feature #523

Merged
merged 12 commits into from
Sep 4, 2022
Merged
1 change: 1 addition & 0 deletions zubhub_backend/zubhub/APIS/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
path('rest-auth/registration/', include('rest_auth.registration.urls')),
path('creators/', include('creators.urls', namespace="creators")),
path('projects/', include('projects.urls', namespace="projects")),
path('activitylog/', include('activitylog.urls', namespace="activitylog")),
path('notifications/', include('notifications.urls', namespace="notifications")),
path('upload-file/', UploadFileAPIView, name="upload_file"),
path('delete-file/', DeleteFileAPIView, name="delete_file"),
Expand Down
1 change: 1 addition & 0 deletions zubhub_backend/zubhub/activitylog/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = 'activitylog.apps.ActivitylogConfig'
6 changes: 6 additions & 0 deletions zubhub_backend/zubhub/activitylog/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.contrib import admin

# Register your models here.
from .models import Activitylog

admin.site.register(Activitylog)
5 changes: 5 additions & 0 deletions zubhub_backend/zubhub/activitylog/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from django.apps import AppConfig


class ActivitylogConfig(AppConfig):
name = 'activitylog'
31 changes: 31 additions & 0 deletions zubhub_backend/zubhub/activitylog/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Generated by Django 3.2 on 2022-08-12 15:11

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import uuid


class Migration(migrations.Migration):

initial = True

dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

operations = [
migrations.CreateModel(
name='Activitylog',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False, unique=True)),
('type', models.PositiveSmallIntegerField(choices=[(1, 'Clap'), (2, 'Comment'), (3, 'Follow'), (4, 'Bookmark')])),
('message', models.CharField(blank=True, max_length=255, null=True)),
('link', models.CharField(blank=True, max_length=1000, null=True)),
('date', models.DateTimeField(default=django.utils.timezone.now)),
('source', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='activitylog_source', to=settings.AUTH_USER_MODEL)),
('target', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='activitylog_target', to=settings.AUTH_USER_MODEL)),
],
),
]
Empty file.
27 changes: 27 additions & 0 deletions zubhub_backend/zubhub/activitylog/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from django.utils import timezone
from django.db import models
import uuid

from creators.models import Creator


class Activitylog(models.Model):
class Type(models.IntegerChoices):
CLAP = 1
COMMENT = 2
FOLLOW = 3
BOOKMARK = 4

id = models.UUIDField(
primary_key=True, default=uuid.uuid4, editable=False, unique=True)
type = models.PositiveSmallIntegerField(
choices=Type.choices,
)
target = models.ForeignKey(
Creator, on_delete=models.CASCADE, null=True, related_name="activitylog_target", blank=True)
source = models.ForeignKey(
Creator, on_delete=models.CASCADE, null=True, related_name="activitylog_source", blank=True)
message = models.CharField(max_length=255, blank=True, null=True)
link = models.CharField(max_length=1000, blank=True, null=True)
date = models.DateTimeField(default=timezone.now)

6 changes: 6 additions & 0 deletions zubhub_backend/zubhub/activitylog/pagination.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from rest_framework.pagination import PageNumberPagination


class ActivitylogNumberPagination(PageNumberPagination):
page_size = 10

12 changes: 12 additions & 0 deletions zubhub_backend/zubhub/activitylog/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from rest_framework.throttling import UserRateThrottle
from django.conf import settings


class SustainedRateThrottle(UserRateThrottle):
scope = 'sustained'

def allow_request(self, request, view):
if settings.DEBUG:
return True
return super().allow_request(request, view)

30 changes: 30 additions & 0 deletions zubhub_backend/zubhub/activitylog/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from creators.models import Creator
from rest_framework import serializers

from .models import Activitylog
from creators.serializers import CreatorMinimalSerializer

class CreatorInfoSerializer(serializers.ModelSerializer):
tags = serializers.SlugRelatedField(slug_field="name",
read_only=True,
many=True)

class Meta:
model = Creator
fields = ('id', 'username', 'followers_count',
'following_count', 'projects_count', "tags",
)


class ActivitylogSerializer(serializers.ModelSerializer):

source = CreatorInfoSerializer()
target = CreatorInfoSerializer()

class Meta:
model = Activitylog
fields = ('id', 'source', 'target', 'date', 'type', 'link', 'message')

read_only_field = [
'id', 'source', 'target', 'date', 'type', 'link', 'message'
]
3 changes: 3 additions & 0 deletions zubhub_backend/zubhub/activitylog/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.
10 changes: 10 additions & 0 deletions zubhub_backend/zubhub/activitylog/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django.urls import path
from .views import *

app_name = "activitylog"

urlpatterns = [
path('',AllUsersActivitylogAPIView.as_view(), name='all-activitylogs' ),
path('<str:username>/',
UserActivitylogAPIView.as_view(), name='user-activitylog')
]
22 changes: 22 additions & 0 deletions zubhub_backend/zubhub/activitylog/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from datetime import datetime, timedelta
from email import message
from activitylog.models import Activitylog
from django.template.loader import render_to_string


def get_activity_template_name(activity_type):
file_extension='.html'
return f'activitylog/{activity_type.name.lower()}{file_extension}'


def push_activity(user, source, context, activity_type, link):
template_name = get_activity_template_name(activity_type)

message= render_to_string(template_name, context)

activity= Activitylog.objects.create(type= activity_type, target= user,
source= source, message= message,
link= link)

activity.save()

28 changes: 28 additions & 0 deletions zubhub_backend/zubhub/activitylog/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from .serializers import ActivitylogSerializer
from .pagination import ActivitylogNumberPagination
from .permissions import SustainedRateThrottle
from rest_framework.permissions import IsAuthenticated

from .models import Activitylog

from rest_framework.generics import ListAPIView
from django.utils.translation import ugettext_lazy as _

from rest_framework.generics import (ListAPIView)

# Create your views here.

class AllUsersActivitylogAPIView(ListAPIView):
serializer_class = ActivitylogSerializer
pagination_class = ActivitylogNumberPagination

def get_queryset(self):
return Activitylog.objects.all()

class UserActivitylogAPIView(ListAPIView):
serializer_class = ActivitylogSerializer
pagination_class = ActivitylogNumberPagination

def get_queryset(self):
username = self.kwargs.get("username")
return Activitylog.objects.all().filter(source__username= username).order_by("-date")
8 changes: 8 additions & 0 deletions zubhub_backend/zubhub/creators/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from creators.tasks import upload_file_task, send_mass_email, send_mass_text, send_whatsapp
from creators.models import Setting
from notifications.models import Notification
from activitylog.models import Activitylog
from activitylog.utils import push_activity
from notifications.utils import push_notification, get_notification_template_name
from creators.models import Creator
from django.template.loader import render_to_string
Expand Down Expand Up @@ -367,6 +369,12 @@ def enforce_creator__creator_tags_constraints(creator, tag):
else:
return creator.tags.all()

def activity_log(target: List[Creator], source: Creator, contexts, activity_type: Activitylog.Type, link: str):
for user, context in zip(target, contexts):
context.update({'source': source.username})
context.update({'target': user.username})

push_activity(user, source, context, activity_type, link)


enabled_notification_settings: Dict[Notification.Type, Set[int]] = {
Expand Down
10 changes: 9 additions & 1 deletion zubhub_backend/zubhub/creators/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from io import StringIO
from django.utils.translation import ugettext_lazy as _
from notifications.models import Notification
from activitylog.models import Activitylog
from rest_framework import status
from django.http import Http404
from django.contrib.auth import get_user_model
Expand Down Expand Up @@ -39,7 +40,7 @@
from .pagination import CreatorNumberPagination
from .utils import (perform_send_phone_confirmation,
perform_send_email_confirmation, process_avatar,
send_group_invite_notification, perform_creator_search, send_notification)
send_group_invite_notification, perform_creator_search, send_notification, activity_log)
from .permissions import IsOwner

Creator = get_user_model()
Expand Down Expand Up @@ -396,6 +397,13 @@ def get_object(self):
obj.save()

send_notification([obj], self.request.user, [{}], Notification.Type.FOLLOW, f'/creators/{self.request.user.username}')
activity_log(
[obj],
self.request.user,
[{}],
Activitylog.Type.FOLLOW,
f'/creators/{obj}'
)
self.request.user.save()

return obj
Expand Down
28 changes: 27 additions & 1 deletion zubhub_backend/zubhub/projects/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
from projects.permissions import (IsOwner, IsStaffOrModerator,
SustainedRateThrottle, PostUserRateThrottle,
GetUserRateThrottle, CustomUserRateThrottle)
from activitylog.models import Activitylog
from .models import Project, Comment, StaffPick, Category, Tag, PublishingRule
from .utils import (ProjectSearchCriteria, project_changed, detect_mentions,
perform_project_search, can_view,
get_published_projects_for_user)
from creators.utils import activity_notification, send_notification
from creators.utils import activity_notification, send_notification, activity_log
from .serializers import (ProjectSerializer, ProjectListSerializer,
CommentSerializer, CategorySerializer, TagSerializer,
StaffPickSerializer)
Expand Down Expand Up @@ -335,6 +336,14 @@ def get_object(self):
f'/projects/{obj.pk}'
)

activity_log(
[obj.creator],
self.request.user,
[{'project': obj.title}],
Activitylog.Type.CLAP,
f'/projects/{obj.pk}'
)

return obj
else:
raise PermissionDenied(
Expand Down Expand Up @@ -377,6 +386,15 @@ def get_object(self):
f'/projects/{obj.pk}'
)

activity_log(
[obj.creator],
self.request.user,
[{'project': obj.title}],
Activitylog.Type.BOOKMARK,
f'/projects/{obj.pk}'
)


return obj
else:
raise PermissionDenied(
Expand Down Expand Up @@ -460,6 +478,14 @@ def create(self, request, *args, **kwargs):
f'/projects/{result.pk}'
)

activity_log(
[result.creator],
self.request.user,
[{'project': result.title}],
Activitylog.Type.COMMENT,
f'/projects/{result.pk}'
)

return Response(ProjectSerializer(result, context={
'request': request
}).data,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<strong>{{ source }}</strong> bookmarked <strong>{{target}}</strong>'s project "{{ project }}"
1 change: 1 addition & 0 deletions zubhub_backend/zubhub/templates/activitylog/clap.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<strong>{{ source }}</strong> clapped on <strong>{{target}}</strong>'s project "{{ project }}"
1 change: 1 addition & 0 deletions zubhub_backend/zubhub/templates/activitylog/comment.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<strong>{{ source }}</strong> commented on <strong>{{target}}</strong>'s project "{{ project }}"
1 change: 1 addition & 0 deletions zubhub_backend/zubhub/templates/activitylog/follow.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<strong>{{ source }}</strong> started following <strong>{{target}}</strong>
3 changes: 2 additions & 1 deletion zubhub_backend/zubhub/zubhub/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@
'APIS',
'creators',
'projects',
'notifications'
'notifications',
'activitylog'
]

# askimet
Expand Down
1 change: 1 addition & 0 deletions zubhub_backend/zubhub/zubhub/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
path('api/rest-auth/password/reset/confirm/', PasswordResetConfirmView.as_view()),
path('api/creators/', include('creators.urls')),
path('api/projects/', include('projects.urls')),
path('api/activitylog/', include('activitylog.urls')),
path('api/upload-file/', UploadFileAPIView),
path('api/delete-file/', DeleteFileAPIView),
path('api/upload-file-to-local/', UploadFileToLocalAPIView),
Expand Down
15 changes: 15 additions & 0 deletions zubhub_frontend/zubhub/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions zubhub_frontend/zubhub/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-i18next": "^11.8.5",
"react-icons": "^4.4.0",
"react-quill": "^1.3.5",
"react-redux": "^7.2.2",
"react-router-dom": "^5.2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,7 @@
"placeholder1": "Tell us more about you by clicking on the edit button at the top of the page 😀!",
"placeholder2": "Tell us more about your group by clicking on the edit button at the top of the page 😀!"
},
"activityLog": "Activity Log",
"projects": {
"label": "Latest projects",
"viewAll": "View all >>"
Expand Down
Loading