Exemplo n.º 1
0
    def picks(self, request, pk=None):
        """
        회원 프로필에서 캐스트(픽) 리스트
        ---
        - 마지막 항번값으로 페이징 처리를 합니다. 첫 페이지 호출할때 last_key 값을 넘기지 않아야 합니다.
        - 회원 프로필에서는 캐스트(픽) 카테고리 정보에 'is_new' 정보는 항상 없습니다.
        """
        response = {}

        get_object_or_404(User, id=pk)

        params = UserPicksForm(data=request.GET)
        params.is_valid(raise_exception=True)
        cursor = params.validated_data.get('cursor')

        if cursor is None:
            response['categories'] = pick_service.get_user_pick_categories(user_id=pk)

        picks, total_count, next_offset = pick_service.get_user_picks(user_id=pk, **params.validated_data)
        response['picks'] = picks
        response['paging'] = dict()
        if total_count:
            response['total_count'] = total_count
        if next_offset:
            response['paging']['next'] = next_offset

        return Response(PickListResponse(response).data)
Exemplo n.º 2
0
    def edit(self, request, pk=None):
        """
        제품 수정 요청
        """
        params = RequestForm(data=request.data)
        params.is_valid(raise_exception=True)

        user_id = int(request.META.get('HTTP_IDREGISTER') or 0)
        user = get_object_or_404(User, id=user_id)
        product = get_object_or_404(Product, id=pk)

        contents = params.validated_data.get('contents')
        now = local_now().strftime('%Y%m%d%H%M%S')

        response = dict()
        try:
            RequestedEditProduct(contents=contents,
                                 product=product,
                                 user=user,
                                 create_date=now).save()

            response['is_success'] = True
            response['message'] = _("소중한 정보 감사합니다! 빠르게 수정하겠습니다:)")
        except:
            response['is_success'] = False
            response['message'] = _("요청 등록에 실패하였습니다.")

        return Response(SuccessMessageResponse(response).data,
                        status=status.HTTP_201_CREATED)
Exemplo n.º 3
0
    def ingredient(self, request, pk=None):
        """
        성분등록요청
        ---
        'file'  키값으로 이미지 파일 전송
        <br><br> 헤더 <br>
        - IDREGISTER:        (필수) 회원 항번 <br>
        """

        user_id = request.META.get('HTTP_IDREGISTER')
        file_obj = request.FILES.get('file')

        user = get_object_or_404(User, id=user_id)
        product = get_object_or_404(Product, id=pk)

        now = local_now().strftime('%Y%m%d%H%M%S')

        response = dict()
        try:
            if file_obj:
                if RequestedIngredient.objects.filter(
                        user=user, product=product).exists():
                    response['is_success'] = False
                    response['message'] = _("이미 성분등록 요청을 하셨습니다.")
                    return Response(SuccessMessageResponse(response).data,
                                    status=status.HTTP_201_CREATED)

                requested_ingredient = RequestedIngredient(user=user,
                                                           product=product,
                                                           create_date=now)
                requested_ingredient.save()

                file_info = store_requested_ingredient_image(
                    file_obj, requested_ingredient.id)

                if file_info:
                    requested_ingredient.file_name_orig = file_info.get(
                        'file_org_name')
                    requested_ingredient.file_name_save = file_info.get(
                        'file_save_name')
                    requested_ingredient.file_dir = file_info.get('file_dir')
                    requested_ingredient.file_size = file_info.get('file_size')
                    requested_ingredient.file_type = file_info.get('file_type')
                    requested_ingredient.save()

                response['is_success'] = True
                response['message'] = _("성분요청이 정상적으로 등록되었습니다.")
            else:
                response['is_success'] = False
                response['message'] = _("성분요청시 성분이미지는 필수 입니다.")
        except:
            response['is_success'] = False
            response['message'] = _("요청 등록에 실패하였습니다.")

        return Response(SuccessMessageResponse(response).data,
                        status=status.HTTP_201_CREATED)
Exemplo n.º 4
0
    def wish(self, request, pk=None):
        """
        위시 확인 / 추가 / 삭제
        ---
        - IDREGISTER:        (필수) 회원 항번 <br>
        """

        cuid = int(request.META.get('HTTP_IDREGISTER') or 0)
        user = get_object_or_404(User, id=cuid)
        product = get_object_or_404(Product, id=pk)

        response = dict()
        if request.method == 'GET':
            if Wish.objects.filter(user=user, product=product).exists():
                response['is_success'] = False
                response['message'] = _("이미 위시리스트에 있습니다.")
            else:
                response['is_success'] = True
                response['message'] = _("위시리스트에 추가할 수 있습니다.")

        elif request.method == 'POST':
            if Wish.objects.filter(user=user, product=product).exists():
                response['is_success'] = False
                response['message'] = _("이미 위시리스트에 있습니다.")
            else:
                try:
                    now = local_now().strftime('%Y%m%d%H%M%S')
                    Wish(user=user, product=product, create_date=now).save()
                    response['is_success'] = True
                    msg_arr = [
                        _("지름신 팍팍! 위시리스트 등록 완료"),
                        _("코덕으로 가는 지름길! 위시리스트 등록 완료~")
                    ]
                    response['message'] = random.choice(msg_arr)
                except:
                    response['is_success'] = False
                    response['message'] = _("추가에 실패하였습니다.")

        elif request.method == 'DELETE':
            qs = Wish.objects.filter(user=user, product=product)
            if qs.exists():
                qs.delete()
                response['is_success'] = True
                response['message'] = _("위시리스트가 삭제되었습니다.")
            else:
                response['is_success'] = False
                response['message'] = _("이미 삭제되었습니다.")

        return Response(
            SuccessMessageResponse(response).data,
            status=status.HTTP_200_OK
        )
Exemplo n.º 5
0
    def check(self, request, pk=None):
        """
        알림함 메세지 체크
        ---
        """
        user_id = self.request.META.get('HTTP_IDREGISTER')
        user = get_object_or_404(User, id=user_id)
        message = get_object_or_404(MessageBox, id=pk)

        obj, created = MessageCheck.objects.get_or_create(user=user,
                                                          message=message)
        obj.read_at = utc_now()
        obj.save()

        return Response(MessageReadSerializer(obj).data,
                        status=status.HTTP_200_OK)
Exemplo n.º 6
0
    def count(self, request):
        """
        알림함 뱃지 카운트
        ---
        """
        # 14일 지난 메세지 삭제 처리
        last_created_at = utc_now() - timedelta(days=14)
        user_id = self.request.META.get('HTTP_IDREGISTER')
        if user_id is None or user_id == '0':
            return Response({'count': 0}, status=status.HTTP_200_OK)
        MessageBox.objects.filter(
            Q(user_id=user_id)
            | Q(user_id__isnull=True, group_id__isnull=True)).filter(
                updated_at__lt=last_created_at,
                is_active=True).update(is_active=False)

        user = get_object_or_404(User, id=user_id)
        joined_at = user.date_joined - timedelta(hours=9)

        query_set = MessageBox.objects.filter(
            Q(user_id=user_id)
            | Q(user_id__isnull=True, group_id__isnull=True)).filter(
                created_at__range=(joined_at, utc_now()),
                is_active=True).distinct()
        count = query_set.exclude(messagecheck__user_id=user_id).count()
        return Response({'count': count}, status=status.HTTP_200_OK)
Exemplo n.º 7
0
    def reports(self, request, pk=None):
        """
        리뷰 신고
        ---
        헤더 값 <br>
        IDREGISTER (필수)
        """
        cuid = int(request.META.get('HTTP_IDREGISTER') or 0)

        params = ReviewReportForm(data=request.data)
        params.is_valid(raise_exception=True)

        client_ip = get_client_ip(request)

        report_type = params.validated_data.get('report_type')
        contents = params.validated_data.get('contents')

        review = get_object_or_404(Review, id=pk)

        if cuid == review.user_id:
            raise InvalidParameterException()

        if review_service.has_report(pk, cuid):
            raise ConflictException(
                _("이미 신고한 리뷰입니다.")
            )

        review_service.create_report(pk, cuid, client_ip, report_type, contents, review.user_id)

        # 리뷰 신고 카운트 증가
        review.report_count += 1
        review.save()

        return Response({}, status=status.HTTP_201_CREATED)
Exemplo n.º 8
0
    def retrieve(self, request, pk=None):
        """
        어워드 수상 제품 전체
        """
        try:
            results = awards_service.get_awards_products_by_dynamodb(
                award_id=pk)
        except:
            get_object_or_404(Awards, id=pk)
            results = awards_service.get_award_products(award_id=pk)

        response = dict()
        response['awards'] = results

        return Response(AwardsCategoryProductsResponse(response).data,
                        status=status.HTTP_200_OK)
Exemplo n.º 9
0
    def retrieve(self, request, pk=None):
        """
        제품 상세 정보
        """
        cuid = int(request.META.get('HTTP_IDREGISTER') or 0)

        product = get_object_or_404(Product, id=pk)

        product.read_count += 1
        product.save()

        response = dict()

        ads_id = None
        try:
            response['product'] = products_service.get_product_detail_dynamodb(product.id)
            month_new = response['product'].get('month_new')
            if month_new:
                ads_id = month_new.get('id')
        except:
            response['product'] = products_service.get_product_detail(product)
            month_new = getattr(response['product'], 'month_new')
            if month_new:
                ads_id = month_new.id

        # ads server
        if ads_id:
            request_ads('GP0010', str(ads_id))

        if cuid > 0:
            user = User.objects.get(id=cuid)

            response['is_wish'] = user.wishes.filter(id=pk).exists()
            if (user._gender is None) or (user._skin_type is None):
                response['is_review_type'] = 'more'
                response['is_review_message'] = _("내정보에서 추가정보를 입력하셔야 작성이 가능합니다.")
            elif Review.objects.filter(user=user, product=product).exists():
                response['is_review_type'] = 'wrote'
                response['is_review_message'] = _("이미 리뷰를 작성한 제품입니다:(\n다른 제품에도 솔직평가 남겨주세요!")
                response['my_review'] = Review.objects.get(user=user, product=product)
            else:
                response['is_review_type'] = 'ok'
        else:
            response['is_wish'] = False
            response['is_review_type'] = "join"
            response['is_review_message'] = _("회원가입이 필요합니다.")

        qs = Review.objects.filter(
            product=pk, is_display=True, state='N', user__is_blinded=0
        )
        rating_avg = qs.aggregate(Avg('rating'))
        if isinstance(response['product'], dict):
            response['product']['rating_avg'] = round(float(rating_avg.get('rating__avg') or 0), 2)
            response['product']['review_count'] = qs.count()
        else:
            setattr(response['product'], 'rating_avg', round(float(rating_avg.get('rating__avg') or 0), 2))
            setattr(response['product'], 'review_count', qs.count())

        return Response(ProductDetailResponse(response).data, status=status.HTTP_200_OK)
Exemplo n.º 10
0
    def guide_ingredient(self, product_id):
        """
        제품 성분 가이드

        높은 위험도 - C05
        중간 위험도 - C04
        낮은 위험도 - C03
        성분 미정 - C02
        성분정보 없음 - C01
        """
        ingredient_guide = {'case': 'C01'}

        product = get_object_or_404(Product, id=product_id)

        if not product.factors_display:
            return ingredient_guide

        ingredients = Ingredient.objects.filter(
            productingredient__product=product_id)

        undefined_ingredients = list(
            filter(lambda x: x.ewg_min is None, ingredients))
        if undefined_ingredients:
            # 성분 미정
            ingredient_guide['case'] = 'C02'
            ingredient_guide['undefined_count'] = len(undefined_ingredients)

        noxious_ingredients = list(
            filter(
                lambda x: (x.ewg_min is not None and x.ewg_min > 6) or
                (x.ewg_max is not None and x.ewg_max > 6), ingredients))
        if noxious_ingredients:
            # 7-10 등급의 성분이 1개 이상인 경우
            ingredient_guide['case'] = 'C05'
            ingredient = noxious_ingredients.pop(0)
            ingredient_guide[
                'noxious_ingredient_name'] = ingredient.korean_name
            if noxious_ingredients:
                ingredient_guide['noxious_ingredient_count'] = len(
                    noxious_ingredients)
        else:
            intermediate_risk_ingredients = list(
                filter(
                    lambda x: (x.ewg_min is not None and x.ewg_min > 2) or
                    (x.ewg_max is not None and x.ewg_max > 2), ingredients))
            if intermediate_risk_ingredients:
                # 3-6 등급의 성분이 포함된 경우
                ingredient_guide['case'] = 'C04'
            else:
                safe_ingredients = list(
                    filter(
                        lambda x: (x.ewg_min is not None and x.ewg_min >= 0) or
                        (x.ewg_min is not None and x.ewg_min >= 0),
                        ingredients))
                if safe_ingredients:
                    # 0-2 등급의 성분으로만 구성된 경우
                    ingredient_guide['case'] = 'C03'

        return ingredient_guide
Exemplo n.º 11
0
    def create(self, request, pick_id=None):
        """
        픽 (캐스트) 댓글 추가
        ---
        <br>
        <b>헤더</b>
        - IDREGISTER:        (필수) 회원 항번 <br>
        """
        cuid = int(request.META.get('HTTP_IDREGISTER') or 0)
        user = get_object_or_404(User, id=cuid)
        pick = get_object_or_404(Pick, pick_id=pick_id)

        params = PickCommentForm(data=request.data)
        params.is_valid(raise_exception=True)

        if not (user.gender and user.skin_type and user.birth_year):
            raise InvalidParameterException(
                _("프로필 편집에서 추가정보를 입력하셔야 참여가 가능합니다.")
            )

        response = dict()
        try:
            with transaction.atomic():
                PickComment(
                    pick=pick,
                    user=user,
                    comment=params.validated_data.get('comment'),
                    ip_address=get_client_ip(request),
                    create_date=local_now().strftime('%Y%m%d%H%M%S')
                ).save()

                # 픽상세 뷰용 업데이트
                aws_dynamodb_pick.update_comment_count(
                    pick_id=pick_id,
                    comment_count=PickComment.objects.filter(pick=pick_id, is_display=True).count() + 1
                )
            response['is_success'] = True
            response['message'] = _("댓글 등록 완료!")
        except:
            response['is_success'] = False
            response['message'] = _("등록에 실패하였습니다.")

        return Response(
            SuccessMessageResponse(response).data,
            status=status.HTTP_201_CREATED
        )
Exemplo n.º 12
0
 def report_types(self, request):
     """
     리뷰 신고 유형 목록
     ---
     """
     type = 'review_report_type_cd'
     common_code = get_object_or_404(CommonCode, code_value=type)
     return Response(
         ReportTypesResponse({"report_types": review_service.get_report_types(common_code)}).data,
         status=status.HTTP_200_OK
     )
Exemplo n.º 13
0
    def wishes(self, request, pk=None):
        """
        회원 프로필에서 위시 리스트
        """

        get_object_or_404(User, id=pk)

        params = UserProductsForm(data=request.GET)
        params.is_valid(raise_exception=True)

        cursor = params.validated_data.get('cursor')

        response = dict()
        response['products'], next_offset = wish_service.get_list(pk, **params.validated_data)
        if cursor is None:
            response['total_count'] = wish_service.get_list(pk, only_count=True, **params.validated_data)
        response['paging'] = dict()
        if next_offset:
            response['paging']['next'] = next_offset

        return Response(UserWishesResponse(response).data)
Exemplo n.º 14
0
 def post(self, request):
     """
     service - ec 간 유저 모델 동기화 처리
     """
     user_id = request.POST.get('user_id')
     user = get_object_or_404(User, id=user_id)
     try:
         obj, created = EcUser.objects.get_or_create(id=user.id)
         for field in user._meta.fields:
             setattr(obj, field.name, getattr(user, field.name))
         obj.save()
     except Exception as err:
         logger.error(str(err))
     return Response(status=status.HTTP_204_NO_CONTENT)
Exemplo n.º 15
0
    def get_queryset(self):
        user_id = self.request.META.get('HTTP_IDREGISTER')

        user = get_object_or_404(User, id=user_id)
        joined_at = user.date_joined - timedelta(hours=9)

        query_set = super(MessageView, self).get_queryset()
        query_set = query_set.select_related('category').filter(
            created_at__range=(joined_at, utc_now())).filter(
                Q(user_id=user_id)
                | Q(user_id__isnull=True, group_id__isnull=True)).exclude(
                    messagecheck__in=MessageCheck.objects.filter(
                        user=user, deleted_at__isnull=False)).distinct()

        return query_set
Exemplo n.º 16
0
    def detail(self, request, pk=None):
        """
        제품 상세 정보
        """
        product = get_object_or_404(Product, id=pk)

        product.read_count += 1
        product.save()

        response = dict()
        try:
            res = products_service.get_product_detail_dynamodb(product.id)
            response['product'] = ProductDetail(res).data
        except:
            response['product'] = ProductDetail(product).data

        return Response(response, status=status.HTTP_200_OK)
Exemplo n.º 17
0
    def products(self, request, pk=None):
        """
        카테고리별 제품 순위 리스트
        """

        category = get_object_or_404(SubCategory, id=pk)

        params = CategoryProductsForm(data=request.GET)
        params.is_valid(raise_exception=True)

        cursor = params.validated_data.get('cursor')

        response = dict()
        results = ranking_service.get_products_ranking_by_category_id(
            category_id=pk, **params.validated_data)

        response['products'] = results.get('list')
        response['paging'] = dict()
        next_offset = results.get('next_offset')
        if next_offset:
            response['paging']['next'] = next_offset

        if cursor is None:
            response['category_info'] = category

            products_count = results.get('products_count')
            if products_count:
                response['total_count'] = products_count

            recommend_product = ranking_service.get_recommend_product_by_sub_category_id(
                category_id=pk)
            if recommend_product:
                response['recommend_products'] = [recommend_product]

                # ads server
                ad_type = recommend_product.get('product_type')
                if ad_type == 'like':
                    request_ads('GP0009', str(recommend_product.get('id')))
                elif ad_type == 'editor':
                    request_ads('GP0012',
                                str(recommend_product.get('product_id')))

        return Response(CategoryProductsResponse(response).data,
                        status=status.HTTP_200_OK)
Exemplo n.º 18
0
    def ingredients(self, request, pk=None):
        """
        제품 성분 리스트
        """
        product = get_object_or_404(Product, id=pk)
        ingredients = Ingredient.objects.filter(
            productingredient__product=pk
        ).order_by(
            'productingredient__seq'
        )

        response = dict()
        response['product'] = product
        response['ingredients'] = ingredients

        return Response(
            ProductIngredientsResponse(response).data,
            status=status.HTTP_200_OK
        )
Exemplo n.º 19
0
    def can_report(self, request, pk=None):
        """
        리뷰 신고 확인
        ---
        헤더 값 <br>
        IDREGISTER (필수)
        """
        cuid = int(request.META.get('HTTP_IDREGISTER') or 0)

        review = get_object_or_404(Review, id=pk)

        if cuid == review.user_id:
            raise InvalidParameterException()

        if review_service.has_report(pk, cuid):
            raise ConflictException(
                _("이미 신고한 리뷰입니다.")
            )

        return Response({}, status=status.HTTP_200_OK)
Exemplo n.º 20
0
    def reviews(self, request, pk=None):
        """
        회원 프로필에서 리뷰 리스트
        """
        cuid = int(request.META.get('HTTP_IDREGISTER') or 0)
        user = get_object_or_404(User, id=pk)

        params = UserReviewsForm(data=request.GET)
        params.is_valid(raise_exception=True)
        cursor = params.validated_data.get('cursor')

        response = dict()
        review_service.setter(user_id=pk)
        results = review_service.get_list(
            request_user_id=cuid,
            user_id=user.id,
            **params.validated_data)

        reviews = list(results['list'] or [])
        response['reviews'] = reviews

        if cursor is None:
            response['total_count'] = review_service.get_list(
                only_count=True,
                request_user_id=cuid,
                user_id=user.id,
                **params.validated_data
            )

        like_count = results.get('like_count')
        if like_count is not None:
            response['like_count'] = results.get('like_count')

        response['paging'] = dict()
        next_offset = results.get('next_offset')
        if next_offset:
            response['paging']['next'] = next_offset

        return Response(UserReviewsResponse(response).data, status=status.HTTP_200_OK)
Exemplo n.º 21
0
    def check(self, request):
        """
        리뷰 작성 확인
        ---
        헤더 값 <br>
        IDREGISTER (필수)
        """
        cuid = int(request.META.get('HTTP_IDREGISTER') or 0)
        if not cuid > 0:
            raise InvalidParameterException(
                _("로그인이 필요합니다.")
            )

        params = ReviewCheckForm(data=request.GET)
        params.is_valid(raise_exception=True)

        product_id = params.validated_data.get('product_id')

        response = dict()

        product = get_object_or_404(Product, id=product_id)
        response['product'] = product

        try:
            review = Review.objects.get(user_id=cuid, product=product)
            blinded_causes = blinded_review_service.get(review.id)
            setattr(review, 'blinded_causes',
                    [OrderedDict(
                        {'cause': item.cause.cause,
                         'guide': item.cause.guide}) for item in blinded_causes])

            response['is_comment'] = True
            response['review'] = review
            response['message'] = _("이미 리뷰를 작성한 제품입니다.\n수정하시겠어요?")

        except Review.DoesNotExist:
            response['is_comment'] = False

        return Response(ReivewCheckResponse(response).data, status=status.HTTP_200_OK)
Exemplo n.º 22
0
    def profile(self, request, pk=None):
        user = get_object_or_404(User, id=pk)
        response = dict()

        if request.method == 'GET':
            response = UserProfileResponse(user)
            return Response(response.data, status=status.HTTP_200_OK)

        elif request.method == 'PUT':
            name = request.POST.get('name')
            contact = request.POST.get('contact')
            zipcode = request.POST.get('zip')
            address = request.POST.get('address')
            address_more = request.POST.get('address_more')

            user.name = name
            user.tel = contact
            user.zipcode = zipcode
            user.address = address
            user.address_more = address_more
            user.save()

        return Response(response, status=status.HTTP_200_OK)
Exemplo n.º 23
0
    def list(self, request, *args, **kwargs):
        """
        알림 메세지 리스트
        ---
        <b>헤더</b>
        - IDREGISTER:        (필수) 회원 항번 <br>

        """
        user_id = self.request.META.get('HTTP_IDREGISTER')
        user = get_object_or_404(User, id=user_id)

        response = super(MessageView, self).list(request, *args, **kwargs)
        query_set = self.get_queryset()
        latest_checked_at = utc_now() - timedelta(days=14)
        query_set = query_set.exclude(id__in=[
            checked.message_id for checked in MessageCheck.objects.filter(
                user=user, checked_at__gte=latest_checked_at)
        ])

        MessageCheck.objects.bulk_create([
            MessageCheck(user=user, message=message) for message in query_set
        ])

        return response
Exemplo n.º 24
0
    def create(self, request):
        """
        새 리뷰 작성
        ---

        <br>
        <b>헤더</b>
        - IDREGISTER:        (필수) 회원 항번 <br>
        """

        # parameters
        cuid = int(request.META.get('HTTP_IDREGISTER') or 0)
        user = get_object_or_404(User, id=cuid)

        review_service.reset_rank(cuid)
        
        params = ReviewWriteForm(data=request.data)
        params.is_valid(raise_exception=True)

        if user.gender is None or user.skin_type is None or user.birth_year is None:
            raise InvalidParameterException(
                _("내정보에서 추가정보를 입력하셔야 작성이 가능합니다.")
            )

        client_ip = get_client_ip(request)
        contents = params.validated_data.get('contents')
        rating = params.validated_data.get('rating')
        product_id = params.validated_data.get('product_id')
        product = get_object_or_404(Product, id=product_id, is_display=True)

        if Review.objects.filter(user=cuid, product=product_id).exists():
            raise ConflictException(
                _("이미 리뷰를 작성한 제품입니다.")
            )

        with transaction.atomic():
            # review insert
            now = local_now().strftime('%Y%m%d%H%M%S')
            review = Review(user=user, product=product, rating=rating, contents=contents, ip_address=client_ip,
                            is_display=True, is_evaluation=False, _created_at=now)

            # 평가단 여부 확인
            if EventPrizeMapping.objects.filter(
                    user=user, product=product
            ).filter(
                event__activity_date__gte=local_now().strftime('%Y%m%d%H%M%S')
            ).exists():
                review.is_evaluation = True

            review.save()

            # user info update
            user.review_count += 1
            user.score += 1
            user.save()

            # product info update
            update_product_info.delay(product_id)

            # tag update
            tags = extract_tags(contents)
            for tag_name in tags:
                tag, created = Tag.objects.get_or_create(name=tag_name)
                if created:
                    TagObject(type='review', object_id=review.id, tag=tag).save()
                    tag.create_date = now
                    tag.save()
                else:
                    if not TagObject.objects.filter(type='review', object_id=review.id, tag=tag).exists():
                        TagObject(type='review', object_id=review.id, tag=tag).save()
                        tag.count += 1
                        tag.modified_date = now
                        tag.save()

            review.tag = ",".join(tags)
            review.save()

            # elastic update
            body = dict()
            # review
            body['idreviewcomment'] = review.id
            body['reviewText'] = contents
            body['rating'] = rating
            body['likeCount'] = 0
            body['isDisplay'] = 1
            body['isEvaluation'] = 0
            body['create_date'] = now
            body['tag'] = ",".join(tags)

            # user
            body['idRegister'] = user.id
            body['nickName'] = user.nickname
            body['birthYear'] = user.birth_year
            body['skinType'] = user._skin_type
            body['gender'] = user._gender
            body['registerScore'] = user.score
            body['registerRank'] = user.rank
            body['isBlind'] = user.is_blinded
            body['registerFileDir'] = user.file_dir
            body['registerFileSaveName'] = user.file_name_save

            # product
            body['idProduct'] = product.id
            body['productTitle'] = product.name
            body['idBrand'] = product.brand_id
            body['productFileDir'] = product.file_dir
            body['productFileSaveName'] = product.file_name
            body['brandTitle'] = product.brand.name
            body['productIsDisplay'] = int(product.is_display)

            categories = product.categories.all().values('id', 'main_category_id')
            body['firstCategoryList'] = ""
            body['secondCategoryList'] = ""
            for category in categories:
                body['firstCategoryList'] += "[" + str(category['main_category_id']) + "]"
                body['secondCategoryList'] += "[" + str(category['id']) + "]"

            try:
                goods_info = ProductGoods.objects.get(product_id=product_id, goods_count__gt=0)
                body['goods_info'] = {
                    "goods_count": goods_info.goods_count,
                    "min_price": goods_info.min_price,
                    "max_price": goods_info.max_price
                }
            except ProductGoods.DoesNotExist:
                pass

            elasticsearch_reviews.add(body=body, _id=review.id)
            
            is_first = not Review.objects.filter(product=product_id).exists()
            
        response = dict()
        response['review_count'] = user.review_set.count()

        # redis 에 update 하는 쿼리
        # 첫 번째 리뷰인지 확인한다.
        
        
        # 첫 리뷰시에 첫 리뷰 관리 테이블에 넣는다.
        if (is_first):
            try:
                Review_first_log(id=product_id, user=user,
                             timestamp=kst_now().strftime("%Y%m%d%H%M%S")
                             ).save(force_insert=True)
            except IntegrityError :
                # 테이블에 접근하는 순간 이미 product 가 존재해서 에러를 띄운다면 처음이 아님으로 is_first 를 False 로 변경한다.
                is_first = False
                
        review_create_cash = {
            'is_first':is_first,
            'written':True
        }
        # review count 에서 사용할 수 있도록 redis 에 set 해준다.
        set_review_is_written(user.id,review_create_cash)
        
        return Response(ReviewWriteResponse(response).data,
                        status=status.HTTP_201_CREATED)
Exemplo n.º 25
0
def update_product_info(product_id):
    """
    제품에 작성된 리뷰를 가지고 점수를 계산한다.
    """

    # product score update
    product = get_object_or_404(Product, id=product_id, is_display=True)

    reviews = Review.objects.filter(product=product, is_display=True, state='N', user__is_blinded=0)

    result = reviews.annotate(
        rating1=Case(When(rating=1, then=1), output_field=IntegerField(), default=0),
        rating2=Case(When(rating=2, then=1), output_field=IntegerField(), default=0),
        rating3=Case(When(rating=3, then=1), output_field=IntegerField(), default=0),
        rating4_1=Case(
            When(Q(rating=4, user__review_count__lte=1), then=1),
            output_field=IntegerField(), default=0
        ),
        rating4_2=Case(
            When(Q(rating=4, user__review_count__gt=1, user__review_count__lte=10), then=1),
            output_field=IntegerField(),
            default=0
        ),
        rating4_3=Case(
            When(Q(rating=4, user__review_count__gt=10, user__review_count__lt=30), then=1),
            output_field=IntegerField(),
            default=0
        ),
        rating4_4=Case(
            When(Q(rating=4, user__review_count__gte=30), then=1),
            output_field=IntegerField(),
            default=0
        ),
        rating5_1=Case(
            When(Q(rating=5, user__review_count__lte=1), then=1),
            output_field=IntegerField(),
            default=0
        ),
        rating5_2=Case(
            When(Q(rating=5, user__review_count__gt=1, user__review_count__lte=10), then=1),
            output_field=IntegerField(),
            default=0
        ),
        rating5_3=Case(
            When(Q(rating=5, user__review_count__gt=10, user__review_count__lt=30), then=1),
            output_field=IntegerField(),
            default=0
        ),
        rating5_4=Case(
            When(Q(rating=5, user__review_count__gte=30), then=1),
            output_field=IntegerField(),
            default=0
        ),
    ).aggregate(
        Sum('rating1'), Sum('rating2'), Sum('rating3'),
        Sum('rating4_1'), Sum('rating4_2'), Sum('rating4_3'), Sum('rating4_4'),
        Sum('rating5_1'), Sum('rating5_2'), Sum('rating5_3'), Sum('rating5_4')
    )

    rating1 = result['rating1__sum']
    rating2 = result['rating2__sum']
    rating3 = result['rating3__sum']

    rating4_1 = result['rating4_1__sum']
    rating4_2 = result['rating4_2__sum']
    rating4_3 = result['rating4_3__sum']
    rating4_4 = result['rating4_4__sum']

    rating5_1 = result['rating5_1__sum']
    rating5_2 = result['rating5_2__sum']
    rating5_3 = result['rating5_3__sum']
    rating5_4 = result['rating5_4__sum']

    # review count
    review_count = rating1 + rating2 + rating3 + \
                   rating4_1 + rating4_2 + rating4_3 + rating4_4 + \
                   rating5_1 + rating5_2 + rating5_3 + rating5_4

    # rating_avg
    rating_avg = (rating1 * 1.0 + rating2 * 2.0 + rating3 * 3.0 + (
        rating4_1 + rating4_2 + rating4_3 + rating4_4) * 4.0 + (
                      rating5_1 + rating5_2 + rating5_3 + rating5_4) * 5) / review_count
    rating_avg = round(rating_avg, 2)

    # product score
    converted_sum = rating1 * -20.0 + rating2 * -10.0 + rating3 * -1.0
    converted_sum += rating4_1 * 0.5 + rating4_2 * 2.5 + rating4_3 * 4.0 + rating4_4 * 5.0
    converted_sum += rating5_1 * 1.0 + rating5_2 * 5.0 + rating5_3 * 8.0 + rating5_4 * 10.0

    if review_count > 70:
        score = converted_sum / review_count * 70
    else:
        score = converted_sum

    review_count_score = review_count * 0.05 if review_count * 0.05 <= 50.0 else 50.0
    score += review_count_score
    score = round(score, 2)

    product.score = score
    product.review_count = review_count
    product.rating_avg = rating_avg
    product.save()

    # dynamo update
    attr_update = {'rating_avg': {'Value': {'N': str(product.rating_avg)}, 'Action': 'PUT'},
                   'review_count': {'Value': {'N': str(product.review_count)}, 'Action': 'PUT'}}
    aws_dynamodb_products.update(product_id, attr_update)

    return product_id
Exemplo n.º 26
0
    def update(self, request, pk=None):
        """
        리뷰 수정
        ---

        <br>
        <b>헤더</b>
        - IDREGISTER:        (필수) 회원 항번 <br>
        """

        # parameters
        cuid = int(request.META.get('HTTP_IDREGISTER') or 0)
        user = get_object_or_404(User, id=cuid)

        params = ReviewUpdateForm(data=request.data)
        params.is_valid(raise_exception=True)

        client_ip = get_client_ip(request)

        contents = params.validated_data.get('contents')
        new_rating = params.validated_data.get('rating')

        review = get_object_or_404(Review, id=pk, user=user, is_display=True)
        product = review.product

        with transaction.atomic():
            # review update
            # 블라인드 상태인 리뷰는 사용자가 수정시 검수중 상태로 변경된다.
            if review.state == 'B':
                review.state = 'C'

            review.ip_address = client_ip
            if contents:
                review.contents = contents
            if new_rating:
                review.rating = new_rating
            review.save()

            # product info update
            update_product_info.delay(product.id)

            # tag update
            tags = extract_tags(contents)
            now = local_now().strftime('%Y%m%d%H%M%S')

            object_tags = TagObject.objects.filter(type='review', object_id=review.id)
            # tag count update
            for _obj in object_tags:
                _obj.tag.count -= 1
                _obj.tag.modified_date = now
                _obj.tag.save()
            # delete tag mapping
            if object_tags.exists():
                object_tags.delete()

            for tag_name in tags:
                tag, created = Tag.objects.get_or_create(name=tag_name)
                if created:
                    TagObject(type='review', object_id=review.id, tag=tag).save()
                    tag.create_date = now
                    tag.save()
                else:
                    if not TagObject.objects.filter(type='review', object_id=review.id, tag=tag).exists():
                        TagObject(type='review', object_id=review.id, tag=tag).save()
                        tag.count += 1
                        tag.modified_date = now
                        tag.save()

            review.tag = ",".join(tags)

            # review update
            review.save()

            # elastic update
            body = {
                "doc": {'rating': new_rating,
                        'reviewText': contents,
                        'tag': ",".join(tags)}
            }
            elasticsearch_reviews.update(_id=review.id, body=body)

        return Response({}, status=status.HTTP_200_OK)
Exemplo n.º 27
0
    def destroy(self, request, pk=None):
        """
        리뷰 삭제
        ---

        <br>
        <b>헤더</b>
        - IDREGISTER:        (필수) 회원 항번 <br>
        """
        cuid = int(request.META.get('HTTP_IDREGISTER') or 0)
        user = get_object_or_404(User, id=cuid)

        try:
            review_service.reset_rank(cuid)
            
            review = get_object_or_404(Review, id=pk, user=user,
                                       is_display=True)
            product = review.product
            
            with transaction.atomic():
                # 해당 리뷰에 블라인드 사유 삭제
                BlindedReview.objects.filter(review_id=pk).delete()
            
                # 좋아요 삭제
                Reviewlike.objects.filter(writer=user, product=product).delete()
            
                # 좋아요 알림 메세지 삭제
                MessageBox.objects.filter(
                    user=user, category=MessageCategory.objects.get(name='좋아요'), reference_id=review.id
                ).update(is_active=False)
            
                # review delete
                review.delete()
            
                # user info update
                user.review_count -= 1
                user.score -= 1
                user.save()
            
                # product info update
                update_product_info.delay(product.id)
            
                # tag update
                object_tags = TagObject.objects.filter(type='review', object_id=pk)
                now = local_now().strftime('%Y%m%d%H%M%S')
                # tag count update
                for _obj in object_tags:
                    _obj.tag.count -= 1
                    _obj.tag.modified_date = now
                    _obj.tag.save()
                # delete tag mapping
                if object_tags.exists():
                    object_tags.delete()
            
                # elastic delete
                elasticsearch_reviews.delete(_id=pk)
            
                # 레디스와 연동하기
                # 처음 리뷰 찾기
                first_review = Review_first_log.objects.filter(
                        id=product.id, user=user).all()[:1]
                
                is_first = len(first_review) > 0
                # 리뷰 포인트 가져오기
                review_points = review_service.get_review_points()
                user_review_count = review_service.get_review_count(user.id)
                this_week_user_review_count = \
                    review_service.get_this_week_review_count(user.id)
                
                score = review_points['review_point'] + \
                        ((user_review_count % 3 == 0) * \
                         review_points['multiple_bonus_point']) + \
                        (is_first * review_points['first_bonus_point'])
            
                
            
                # 처음 기존 리뷰 삭제
                if is_first is True:
                    first_review[0].delete()
            
                    # 처음 리뷰 검색후 넣어주기
                    new_first_reviews = Review.objects.filter(
                        product=product).order_by('_created_at').all()[:2]
            
                    # 최초 하나는 내 리뷰임으로 두번째 것을 넣어준다.
                    if len(new_first_reviews) > 1:
                        # 넣어준다
                        Review_first_log(
                            id=product.id, user=new_first_reviews[1].user,
                            timestamp=new_first_reviews[1]._created_at).save()
            
                        
            # 레디스는 automic 이 적용되지 않음으로 rdb 에서 동작을 마무리한 후 redis 에
            # 적용한다.
            # 삭제로 리뷰가 0개가 되는 순간 배치에서 감지하지 않음으로 주의해야 한다.

            # 레디스에 스코어 값 감소시키기
            # 리뷰가 정상이면
            if review.state == "N" and review.when_seceded == 0 and review.is_display == True and review.user.is_active == 1 and review.user.is_blinded == 0 and review.user.is_black == 0  :
                # 리뷰가 마지막이었다면
                if user_review_count == 1:
                    # rank 에서 삭제
                    period_zrem('all', user.id)
                else:
                    # 아니면 감소
                    period_zincrby('all', user.id, -score)
                
                # review 에 _created_at 은 kst 가 기준이기 떄문에 kst 로 비교한다
                if iso8601(datetime.strptime(
                        review._created_at, "%Y%m%d%H%M%S")) > \
                        iso8601(kst_last_week_friday_18_00()):
                    # 이번주 리뷰가 마지막이었다면
                    if  this_week_user_review_count == 1:
                        # 삭제한다
                        period_zrem('this_week', user.id)
                    else:
                        # 아니면 감소
                        period_zincrby('this_week', user.id, -score)
                # 처음 리뷰가 맞고 다른 사람이 쓴 것이 있으면
                if is_first is True and len(new_first_reviews) > 1:
                    # 처음 리뷰로 등록된 유저 보너스 점수 레디스에 등록하기
                    period_zincrby('all', new_first_reviews[1].user.id,
                                   review_points['first_bonus_point'])
                    if review._created_at > \
                            iso8601(kst_last_week_friday_18_00()):
                        period_zincrby('this_week',
                                   new_first_reviews[1].user.id,
                                   review_points['first_bonus_point'])
        except:
            raise

        
        
        return Response({}, status=status.HTTP_200_OK)
Exemplo n.º 28
0
    def like(self, request, pk=None):
        """
        리뷰 좋아요
        ---
        헤더 값 <br>
        IDREGISTER (필수)
        """
        from django.utils import timezone
        from libs.utils import utc_now

        cuid = int(request.META.get('HTTP_IDREGISTER') or 0)
        try:
            register = User.objects.get(id=cuid, is_active=True)
        except:
            raise InvalidParameterException(
                _("로그인이 필요합니다.")
            )

        review = get_object_or_404(Review, id=pk)
        product = review.product
        writer = review.user

        response = dict()

        if register.id == writer.id:
            raise ConflictException(
                _("나의 리뷰에는 좋아요 하실 수 없습니다.")
            )

        if Reviewlike.objects.filter(writer=writer, product=product, register=cuid).exists():
            raise ConflictException(
                _("이미 좋아요 하셨습니다.")
            )

        created_at = utc_now()
        create_date = format_round_datetime(created_at.astimezone(tz=timezone.get_current_timezone()))
        with transaction.atomic():
            # add one
            Reviewlike(
                writer=writer,
                product=product,
                register=register,
                create_date=create_date
            ).save()

            # writer info update
            user_updated_info = users_service.get_user_score_info(writer.id)
            writer.review_count = user_updated_info.get('review_count')
            writer.like_count = user_updated_info.get('like_count')
            writer.score = user_updated_info.get('score')
            writer.save()

            # review like count update
            review.like_count = Reviewlike.objects.using('default').filter(writer=writer, product=product).count()
            review.save()

            # elastic update
            body = {
                "doc": {'likeCount': review.like_count}
            }
            elasticsearch_reviews.update(_id=review.id, body=body)

        # 알림함
        try:
            review_service.make_like_message(review.id, register.id, created_at)
        except:
            pass

        # send push message
        push_text = "{} 님이 내 리뷰를 좋아합니다.\n{} - {}".format(
            register.nickname, product.brand.name, product.name
        )
        try:
            send_push_message(
                push_text,
                link_type=17,
                link_code=product.id,
                target_id=writer.id,
            )
        except:
            pass

        response['is_success'] = True
        response['message'] = _("좋아요 되었습니다.")

        return Response(SuccessMessageResponse(response).data, status=status.HTTP_201_CREATED)