From 930c10b578e1add27da0bf280e9ae5e99f1d99d4 Mon Sep 17 00:00:00 2001 From: jain Date: Tue, 22 Aug 2023 11:28:52 +0530 Subject: [PATCH 1/2] swagger update --- account/views.py | 59 ++++++++++++++++++++++---- guardian/views.py | 17 +++++--- junior/views.py | 87 ++++++++++++++++++++++++++++---------- notifications/views.py | 6 ++- web_admin/views/article.py | 8 +++- 5 files changed, 137 insertions(+), 40 deletions(-) diff --git a/account/views.py b/account/views.py index d26703d..e4051f4 100644 --- a/account/views.py +++ b/account/views.py @@ -117,13 +117,22 @@ class GoogleLoginViewSet(GoogleLoginMixin, viewsets.GenericViewSet): serializer_class = GoogleLoginSerializer def create(self, request): - """create method""" + """Payload + { + "access_token", + "user_type": "1" + }""" serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) return self.google_login(request) class SigninWithApple(views.APIView): - """This API is for sign in with Apple for app.""" + """This API is for sign in with Apple for app. + Payload + { + "access_token", + "user_type": "1" + }""" def post(self, request): token = request.data.get("access_token") user_type = request.data.get("user_type") @@ -202,6 +211,10 @@ class ChangePasswordAPIView(views.APIView): def post(self, request): """ POST request to change current login user password + Payload + { "current_password":"Demo@123", + "new_password":"Demo@123" + } """ serializer = ChangePasswordSerializer( context=request.user, @@ -219,7 +232,12 @@ class ChangePasswordAPIView(views.APIView): ) class ResetPasswordAPIView(views.APIView): - """Reset password""" + """Reset password + Payload + { + "verification_code":"373770", + "password":"Demo@1323" + }""" def post(self, request): serializer = ResetPasswordSerializer(data=request.data) if serializer.is_valid(): @@ -236,7 +254,10 @@ class ForgotPasswordAPIView(views.APIView): def post(self, request): """ - Post method to validate serializer + Payload + { + "email": "abc@yopmail.com" + } """ serializer = self.serializer_class(data=request.data) serializer.is_valid(raise_exception=True) @@ -420,7 +441,12 @@ class AdminLoginViewSet(viewsets.GenericViewSet): class UserEmailVerification(viewsets.ModelViewSet): - """User Email verification""" + """User Email verification + Payload + { + "email":"ramu@yopmail.com", + "otp":"361123" + }""" serializer_class = EmailVerificationSerializer http_method_names = ('post',) @@ -495,7 +521,9 @@ class ProfileAPIViewSet(viewsets.ModelViewSet): http_method_names = ('get',) def list(self, request, *args, **kwargs): - """profile view""" + """profile view + Params + user_type""" if str(self.request.GET.get('user_type')) == '1': junior_data = Junior.objects.filter(auth=self.request.user).last() if junior_data: @@ -510,6 +538,7 @@ class ProfileAPIViewSet(viewsets.ModelViewSet): class UploadImageAPIViewSet(viewsets.ModelViewSet): """upload task image""" serializer_class = DefaultTaskImagesSerializer + http_method_names = ('post',) def create(self, request, *args, **kwargs): """upload images""" image_data = request.data['image_url'] @@ -529,6 +558,7 @@ class DefaultImageAPIViewSet(viewsets.ModelViewSet): """Profile viewset""" serializer_class = DefaultTaskImagesDetailsSerializer permission_classes = [IsAuthenticated] + http_method_names = ('get',) def list(self, request, *args, **kwargs): """profile view""" queryset = DefaultTaskImages.objects.all() @@ -565,8 +595,9 @@ class UserNotificationAPIViewSet(viewsets.ModelViewSet): """notification viewset""" serializer_class = UserNotificationSerializer permission_classes = [IsAuthenticated] + http_method_names = ('get',) def list(self, request, *args, **kwargs): - """profile view""" + """notification view""" queryset = UserNotification.objects.filter(user=request.user) serializer = UserNotificationSerializer(queryset, many=True) return custom_response(None, serializer.data, response_status=status.HTTP_200_OK) @@ -576,9 +607,14 @@ class UpdateUserNotificationAPIViewSet(viewsets.ModelViewSet): """Update notification viewset""" serializer_class = UpdateUserNotificationSerializer permission_classes = [IsAuthenticated] + http_method_names = ('post',) def create(self, request, *args, **kwargs): - """profile view""" + """Payload + {"email_notification": false, + "sms_notification": false, + "push_notification": false} + """ serializer = UpdateUserNotificationSerializer(data=request.data, context=request.user) if serializer.is_valid(): @@ -588,7 +624,12 @@ class UpdateUserNotificationAPIViewSet(viewsets.ModelViewSet): class SendSupportEmail(views.APIView): - """support email api""" + """support email api + payload + name + email + message + """ permission_classes = (IsAuthenticated,) def post(self, request): diff --git a/guardian/views.py b/guardian/views.py index 843ab45..dd3a1ec 100644 --- a/guardian/views.py +++ b/guardian/views.py @@ -129,7 +129,11 @@ class AllTaskListAPIView(viewsets.ModelViewSet): class TaskListAPIView(viewsets.ModelViewSet): - """Update guardian profile""" + """Task list + Params + status + search + page""" serializer_class = TaskDetailsSerializer permission_classes = [IsAuthenticated] filter_backends = (SearchFilter,) @@ -206,7 +210,7 @@ class CreateTaskAPIView(viewsets.ModelViewSet): return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) class SearchTaskListAPIView(viewsets.ModelViewSet): - """Update guardian profile""" + """Filter task""" serializer_class = TaskDetailsSerializer permission_classes = [IsAuthenticated] pagination_class = PageNumberPagination @@ -221,7 +225,7 @@ class SearchTaskListAPIView(viewsets.ModelViewSet): return junior_queryset def list(self, request, *args, **kwargs): - """Create guardian profile""" + """Filter task""" try: queryset = self.get_queryset() paginator = self.pagination_class() @@ -235,10 +239,12 @@ class SearchTaskListAPIView(viewsets.ModelViewSet): class TopJuniorListAPIView(viewsets.ModelViewSet): - """Top juniors list""" + """Top juniors list + No Params""" queryset = JuniorPoints.objects.all() serializer_class = TopJuniorSerializer permission_classes = [IsAuthenticated] + http_method_names = ('get',) def get_serializer_context(self): # context list @@ -349,7 +355,8 @@ class GuardianListAPIView(viewsets.ModelViewSet): http_method_names = ('get',) def list(self, request, *args, **kwargs): - """ junior list""" + """ Guardian list of assosicated junior + No Params""" try: guardian_data = JuniorGuardianRelationship.objects.filter(junior__auth__email=self.request.user) # fetch junior object diff --git a/junior/views.py b/junior/views.py index 1ed3972..62c5fff 100644 --- a/junior/views.py +++ b/junior/views.py @@ -74,7 +74,7 @@ class UpdateJuniorProfile(viewsets.ModelViewSet): http_method_names = ('post',) def create(self, request, *args, **kwargs): - """Use CreateJuniorSerializer""" + """Create Junior Profile""" try: request_data = request.data image = request.data.get('image') @@ -104,9 +104,13 @@ class UpdateJuniorProfile(viewsets.ModelViewSet): class ValidateGuardianCode(viewsets.ModelViewSet): """Check guardian code exist or not""" permission_classes = [IsAuthenticated] + http_method_names = ('get',) def list(self, request, *args, **kwargs): - """check guardian code""" + """check guardian code + Params + "guardian_code" + """ try: guardian_code = self.request.GET.get('guardian_code').split(',') for code in guardian_code: @@ -216,7 +220,7 @@ class AddJuniorAPIView(viewsets.ModelViewSet): class InvitedJuniorAPIView(viewsets.ModelViewSet): - """Junior list of assosicated guardian""" + """Invited Junior list of assosicated guardian""" serializer_class = JuniorDetailListSerializer permission_classes = [IsAuthenticated] @@ -230,7 +234,8 @@ class InvitedJuniorAPIView(viewsets.ModelViewSet): is_invited=True) return junior_queryset def list(self, request, *args, **kwargs): - """ junior list""" + """ Invited Junior list of assosicated guardian + No Params""" try: queryset = self.get_queryset() paginator = self.pagination_class() @@ -273,7 +278,7 @@ class FilterJuniorAPIView(viewsets.ModelViewSet): return queryset def list(self, request, *args, **kwargs): - """Create guardian profile""" + """Filter junior""" try: queryset = self.get_queryset() paginator = self.pagination_class() @@ -287,7 +292,9 @@ class FilterJuniorAPIView(viewsets.ModelViewSet): class RemoveJuniorAPIView(views.APIView): - """Remove junior API""" + """Remove junior API + Params + id=37""" serializer_class = RemoveJuniorSerializer model = Junior permission_classes = [IsAuthenticated] @@ -315,14 +322,17 @@ class RemoveJuniorAPIView(views.APIView): class JuniorTaskListAPIView(viewsets.ModelViewSet): - """Update guardian profile""" + """Junior task list""" serializer_class = TaskDetailsjuniorSerializer permission_classes = [IsAuthenticated] pagination_class = PageNumberPagination http_method_names = ('get',) def list(self, request, *args, **kwargs): - """Create guardian profile""" + """Junior task list + status=0 + search='title' + page=1""" try: status_value = self.request.GET.get('status') search = self.request.GET.get('search') @@ -352,7 +362,9 @@ class JuniorTaskListAPIView(viewsets.ModelViewSet): class CompleteJuniorTaskAPIView(views.APIView): - """Update junior task API""" + """Payload + task_id + image""" serializer_class = CompleteTaskSerializer model = JuniorTask permission_classes = [IsAuthenticated] @@ -397,7 +409,8 @@ class JuniorPointsListAPIView(viewsets.ModelViewSet): http_method_names = ('get',) def list(self, request, *args, **kwargs): - """profile view""" + """Junior Points + No Params""" try: update_positions_based_on_points() queryset = JuniorPoints.objects.filter(junior__auth__email=self.request.user).last() @@ -467,7 +480,11 @@ class InviteGuardianAPIView(viewsets.ModelViewSet): class StartTaskAPIView(views.APIView): - """Update junior task API""" + """Update junior task API + Paylod + { + "task_id":28 + }""" serializer_class = StartTaskSerializer model = JuniorTask permission_classes = [IsAuthenticated] @@ -491,7 +508,13 @@ class StartTaskAPIView(views.APIView): return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) class ReAssignJuniorTaskAPIView(views.APIView): - """Update junior task API""" + """Update junior task API + Payload + { + "task_id":34, + "due_date":"2023-08-22" + } + """ serializer_class = ReAssignTaskSerializer model = JuniorTask permission_classes = [IsAuthenticated] @@ -520,7 +543,10 @@ class StartArticleAPIView(viewsets.ModelViewSet): http_method_names = ('post',) def create(self, request, *args, **kwargs): - """ junior list""" + """ Payload + { + "article_id":"2" + }""" try: junior_instance = Junior.objects.filter(auth=self.request.user).last() article_id = request.data.get('article_id') @@ -542,7 +568,7 @@ class StartArticleAPIView(viewsets.ModelViewSet): return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) class StartAssessmentAPIView(viewsets.ModelViewSet): - """Junior Points viewset""" + """Question answer viewset""" serializer_class = StartAssessmentSerializer permission_classes = [IsAuthenticated] http_method_names = ('get',) @@ -555,7 +581,9 @@ class StartAssessmentAPIView(viewsets.ModelViewSet): ).order_by('-created_at') return article def list(self, request, *args, **kwargs): - """profile view""" + """Params + article_id + """ try: queryset = self.get_queryset() @@ -567,7 +595,9 @@ class StartAssessmentAPIView(viewsets.ModelViewSet): return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) class CheckAnswerAPIView(viewsets.ModelViewSet): - """Junior Points viewset""" + """Params + question_id=1 + answer_id=1""" permission_classes = [IsAuthenticated] http_method_names = ('get',) @@ -576,7 +606,10 @@ class CheckAnswerAPIView(viewsets.ModelViewSet): article = ArticleSurvey.objects.filter(id=question_id).last() return article def list(self, request, *args, **kwargs): - """profile view""" + """ Params + question_id=1 + answer_id=1 + """ try: answer_id = self.request.GET.get('answer_id') @@ -600,7 +633,9 @@ class CheckAnswerAPIView(viewsets.ModelViewSet): return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) class CompleteArticleAPIView(views.APIView): - """Remove junior API""" + """Params + article_id + """ permission_classes = [IsAuthenticated] http_method_names = ('put', 'get',) def put(self, request, format=None): @@ -614,7 +649,8 @@ class CompleteArticleAPIView(views.APIView): return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) def get(self, request, *args, **kwargs): - """ junior list""" + """ Params + article_id=1""" try: article_id = self.request.GET.get('article_id') total_earn_points = JuniorArticlePoints.objects.filter(junior__auth=request.user, @@ -628,12 +664,16 @@ class CompleteArticleAPIView(views.APIView): class ReadArticleCardAPIView(views.APIView): - """Remove junior API""" + """Read article card API""" permission_classes = [IsAuthenticated] http_method_names = ('put',) def put(self, request, *args, **kwargs): - """ junior list""" + """ Read article card + Payload + {"article_id":"1", + "article_card":"2", + "current_page":"2"}""" try: junior_instance = Junior.objects.filter(auth=self.request.user).last() article = self.request.data.get('article_id') @@ -677,7 +717,8 @@ class CreateArticleCardAPIView(viewsets.ModelViewSet): return custom_error_response(str(e), response_status=status.HTTP_400_BAD_REQUEST) class RemoveGuardianCodeAPIView(views.APIView): - """Update junior task API""" + """Remove guardian code request API + No Payload""" serializer_class = RemoveGuardianCodeSerializer permission_classes = [IsAuthenticated] @@ -714,7 +755,7 @@ class FAQViewSet(GenericViewSet, mixins.CreateModelMixin, """ faq create api method :param request: - :param args: + :param args: question, description :param kwargs: :return: success message """ diff --git a/notifications/views.py b/notifications/views.py index 5adb536..154751a 100644 --- a/notifications/views.py +++ b/notifications/views.py @@ -77,7 +77,11 @@ class NotificationViewSet(viewsets.GenericViewSet): class ReadNotification(views.APIView): - """Update notification API""" + """Update notification API + Payload + { + "notification_id": [] + }""" serializer_class = ReadNotificationSerializer model = Notification permission_classes = [IsAuthenticated] diff --git a/web_admin/views/article.py b/web_admin/views/article.py index 49f76fa..6570f6f 100644 --- a/web_admin/views/article.py +++ b/web_admin/views/article.py @@ -248,7 +248,9 @@ class ArticleListViewSet(GenericViewSet, mixins.ListModelMixin): return custom_response(None, data=serializer.data) class ArticleCardListViewSet(viewsets.ModelViewSet): - """Junior Points viewset""" + """Article card list + use below query param + article_id""" serializer_class = ArticleCardlistSerializer permission_classes = [IsAuthenticated] http_method_names = ('get',) @@ -257,7 +259,9 @@ class ArticleCardListViewSet(viewsets.ModelViewSet): """get queryset""" return ArticleCard.objects.filter(article=self.request.GET.get('article_id')) def list(self, request, *args, **kwargs): - """profile view""" + """Article card list + use below query param + article_id""" try: queryset = self.get_queryset() From f8e529600b29c799bdb5a07ff6079d9b46433b90 Mon Sep 17 00:00:00 2001 From: jain Date: Tue, 22 Aug 2023 13:46:37 +0530 Subject: [PATCH 2/2] force update and mail by celery task --- account/custom_middleware.py | 6 +++++- account/migrations/0010_forceupdate.py | 28 ++++++++++++++++++++++++++ account/models.py | 24 +++++++++++++++++++++- account/views.py | 2 +- base/constants.py | 5 ++++- guardian/views.py | 2 +- junior/serializers.py | 6 +++--- junior/utils.py | 4 +++- 8 files changed, 68 insertions(+), 9 deletions(-) create mode 100644 account/migrations/0010_forceupdate.py diff --git a/account/custom_middleware.py b/account/custom_middleware.py index c2125cd..3193fa9 100644 --- a/account/custom_middleware.py +++ b/account/custom_middleware.py @@ -5,7 +5,7 @@ from rest_framework.response import Response from rest_framework.renderers import JSONRenderer """App django""" from account.utils import custom_error_response -from account.models import UserDeviceDetails +from account.models import UserDeviceDetails, ForceUpdate from base.messages import ERROR_CODE, SUCCESS_CODE from base.constants import NUMBER from junior.models import Junior @@ -39,6 +39,8 @@ class CustomMiddleware(object): # Code to be executed after the view is called device_id = request.META.get('HTTP_DEVICE_ID') user_type = request.META.get('HTTP_USER_TYPE') + version = request.META.get('HTTP_VERSION') + device_type = str(request.META.get('HTTP_TYPE')) api_endpoint = request.path if request.user.is_authenticated: # device details @@ -56,4 +58,6 @@ class CustomMiddleware(object): if device_id and not device_details and api_endpoint != '/api/v1/user/login/': custom_error = custom_error_response(ERROR_CODE['2037'], response_status=status.HTTP_404_NOT_FOUND) response = custom_response(custom_error) + force_update = ForceUpdate.objects.filter(version=version, device_type=device_type).last() + return response diff --git a/account/migrations/0010_forceupdate.py b/account/migrations/0010_forceupdate.py new file mode 100644 index 0000000..84f5b12 --- /dev/null +++ b/account/migrations/0010_forceupdate.py @@ -0,0 +1,28 @@ +# Generated by Django 4.2.2 on 2023-08-22 07:39 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('account', '0009_alter_userdevicedetails_device_id'), + ] + + operations = [ + migrations.CreateModel( + name='ForceUpdate', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('version', models.CharField(blank=True, max_length=50, null=True)), + ('device_type', models.CharField(blank=True, choices=[('1', 'android'), ('2', 'ios')], default=None, max_length=15, null=True)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + options={ + 'verbose_name': 'Force Update Version', + 'verbose_name_plural': 'Force Update Version', + 'db_table': 'force_update', + }, + ), + ] diff --git a/account/models.py b/account/models.py index 784a60e..c71181e 100644 --- a/account/models.py +++ b/account/models.py @@ -3,7 +3,7 @@ from django.db import models from django.contrib.auth.models import User """App import""" -from base.constants import USER_TYPE +from base.constants import USER_TYPE, DEVICE_TYPE # Create your models here. class UserProfile(models.Model): @@ -165,3 +165,25 @@ class UserDeviceDetails(models.Model): def __str__(self): return self.user.email + + + + +class ForceUpdate(models.Model): + """ + Force update + """ + """Version ID""" + version = models.CharField(max_length=50, null=True, blank=True) + device_type = models.CharField(max_length=15, choices=DEVICE_TYPE, null=True, blank=True, default=None) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + class Meta(object): + """ Meta information """ + db_table = 'force_update' + verbose_name = 'Force Update Version' + verbose_name_plural = 'Force Update Version' + + def __str__(self): + return self.version diff --git a/account/views.py b/account/views.py index e4051f4..84b6aaa 100644 --- a/account/views.py +++ b/account/views.py @@ -509,7 +509,7 @@ class ReSendEmailOtp(viewsets.ModelViewSet): email_data.otp = otp email_data.expired_at = expiry email_data.save() - send_otp_email(request.data['email'], otp) + send_otp_email.delay(request.data['email'], otp) return custom_response(SUCCESS_CODE['3016'], response_status=status.HTTP_200_OK) else: return custom_error_response(ERROR_CODE["2023"], response_status=status.HTTP_400_BAD_REQUEST) diff --git a/base/constants.py b/base/constants.py index d376971..1ab15a2 100644 --- a/base/constants.py +++ b/base/constants.py @@ -50,7 +50,10 @@ USER_TYPE = ( ('2', 'guardian'), ('3', 'superuser') ) - +DEVICE_TYPE = ( + ('1', 'android'), + ('2', 'ios') +) USER_TYPE_FLAG = { "FIRST" : "1", "TWO" : "2", diff --git a/guardian/views.py b/guardian/views.py index dd3a1ec..80c1d9b 100644 --- a/guardian/views.py +++ b/guardian/views.py @@ -73,7 +73,7 @@ class SignupViewset(viewsets.ModelViewSet): UserEmailOtp.objects.create(email=request.data['email'], otp=otp, user_type=str(request.data['user_type']), expired_at=expiry) """Send email to the register user""" - send_otp_email(request.data['email'], otp) + send_otp_email.delay(request.data['email'], otp) UserDeviceDetails.objects.create(user=user, device_id=device_id) return custom_response(SUCCESS_CODE['3001'], response_status=status.HTTP_200_OK) diff --git a/junior/serializers.py b/junior/serializers.py index 1ca98e4..01e5adc 100644 --- a/junior/serializers.py +++ b/junior/serializers.py @@ -97,7 +97,7 @@ class CreateJuniorSerializer(serializers.ModelSerializer): if guardian_data: JuniorGuardianRelationship.objects.get_or_create(guardian=guardian_data, junior=junior) junior.guardian_code_status = str(NUMBER['three']) - junior_approval_mail(user.email, user.first_name) + junior_approval_mail.delay(user.email, user.first_name) send_notification_to_guardian.delay(APPROVED_JUNIOR, junior.auth.id, guardian_data.user.id, {}) junior.dob = validated_data.get('dob', junior.dob) junior.passcode = validated_data.get('passcode', junior.passcode) @@ -304,7 +304,7 @@ class AddJuniorSerializer(serializers.ModelSerializer): # add push notification UserNotification.objects.get_or_create(user=user_data) """Notification email""" - junior_notification_email(email, full_name, email, password) + junior_notification_email.delay(email, full_name, email, password) # push notification send_notification_to_junior.delay(SKIPPED_PROFILE_SETUP, None, junior_data.auth.id, {}) return junior_data @@ -450,7 +450,7 @@ class AddGuardianSerializer(serializers.ModelSerializer): """Notification email""" junior_notification_email(email, full_name, email, password) - junior_approval_mail(email, full_name) + junior_approval_mail.delay(email, full_name) send_notification_to_junior.delay(INVITATION, guardian_data.user.id, junior_data.auth.id, {}) send_notification_to_guardian.delay(ASSOCIATE_REQUEST, junior_data.auth.id, guardian_data.user.id, {}) return guardian_data diff --git a/junior/utils.py b/junior/utils.py index ba177a8..4a6ee2b 100644 --- a/junior/utils.py +++ b/junior/utils.py @@ -14,6 +14,8 @@ from django.db.models import F # being part of the zod bank and access the platform # define junior notification email # junior approval email +from celery import shared_task +@shared_task() def junior_notification_email(recipient_email, full_name, email, password): """Notification email""" from_email = settings.EMAIL_FROM_ADDRESS @@ -32,7 +34,7 @@ def junior_notification_email(recipient_email, full_name, email, password): } ) return full_name - +@shared_task() def junior_approval_mail(guardian, full_name): """junior approval mail""" from_email = settings.EMAIL_FROM_ADDRESS