示例#1
0
def uninterested(request, bounty_id, profile_id):
    """Remove party from given bounty

    Can only be called by the bounty funder

    :request method: GET

    Args:
        bounty_id (int): ID of the Bounty
        profile_id (int): ID of the interested profile

    Returns:
        dict: The success key with a boolean value and accompanying error.
    """
    try:
        bounty = Bounty.objects.get(pk=bounty_id)
    except Bounty.DoesNotExist:
        return JsonResponse({'errors': ['Bounty doesn\'t exist!']}, status=401)

    is_funder = bounty.is_funder(request.user.username.lower())
    is_staff = request.user.is_staff
    if not is_funder and not is_staff:
        return JsonResponse(
            {'error': 'Only bounty funders are allowed to remove users!'},
            status=401)

    try:
        interest = Interest.objects.get(profile_id=profile_id, bounty=bounty)
        bounty.interested.remove(interest)
        maybe_market_to_slack(bounty, 'stop_work')
        maybe_market_to_user_slack(bounty, 'stop_work')
        event_name = "bounty_removed_by_staff" if is_staff else "bounty_removed_by_funder"
        record_user_action_on_interest(interest, event_name, None)
        interest.delete()
    except Interest.DoesNotExist:
        return JsonResponse(
            {
                'errors':
                ['Party haven\'t expressed interest on this bounty.'],
                'success': False
            },
            status=401)
    except Interest.MultipleObjectsReturned:
        interest_ids = bounty.interested \
            .filter(
                profile_id=profile_id,
                bounty=bounty
            ).values_list('id', flat=True) \
            .order_by('-created')

        bounty.interested.remove(*interest_ids)
        Interest.objects.filter(pk__in=list(interest_ids)).delete()

    profile = Profile.objects.get(id=profile_id)
    if profile.user and profile.user.email:
        bounty_uninterested(profile.user.email, bounty, interest)
    else:
        print("no email sent -- user was not found")
    return JsonResponse({'success': True})
示例#2
0
    def handle(self, *args, **options):
        if settings.DEBUG:
            print('not running start work expiration because DEBUG is on')
            return

        # TODO: DRY with dashboard/notifications.py
        num_days_back_to_warn = 3
        num_days_back_to_delete_interest = 6
        num_days_back_to_ignore_bc_mods_got_it = 9

        days = [i * 3 for i in range(1, 15)]
        days.reverse()
        if settings.DEBUG:
            days = range(1, 1000)
        for day in days:
            start_date = (timezone.now() - timezone.timedelta(days=(day + 1)))
            end_date = (timezone.now() - timezone.timedelta(days=day))

            interests = Interest.objects.select_related("profile").filter(
                Q(created__gte=start_date, created__lt=end_date)
                | Q(acceptance_date__gte=start_date,
                    acceptance_date__lt=end_date),
                pending=False).distinct('pk')

            print(f'day {day} got {interests.count()} interests')
            for interest in interests:

                if interest.acceptance_date:
                    interest_day_0 = interest.acceptance_date
                    bounties = Bounty.objects.current().filter(
                        interested=interest,
                        project_type='traditional',
                        network='mainnet',
                        idx_status__in=['open', 'started'],
                        permission_type='approval',
                    )
                else:
                    interest_day_0 = interest.created
                    bounties = Bounty.objects.current().filter(
                        interested=interest,
                        project_type='traditional',
                        network='mainnet',
                        idx_status__in=['open', 'started'],
                        permission_type='permissionless',
                    )

                for bounty in bounties:
                    print("===========================================")
                    print(
                        f"{interest} is interested in {bounty.pk} / {bounty.github_url}"
                    )
                    try:
                        actions = get_interested_actions(
                            bounty.github_url, interest.profile.handle,
                            interest.profile.email)
                        should_warn_user = False
                        should_delete_interest = False
                        should_ignore = False
                        last_heard_from_user_days = None

                        if not actions:
                            should_warn_user = True
                            should_delete_interest = False
                            last_heard_from_user_days = (timezone.now() -
                                                         interest_day_0).days
                            print(" - no actions")
                        else:
                            # example format: 2018-01-26T17:56:31Z'
                            action_times = [
                                datetime.strptime(action['created_at'],
                                                  '%Y-%m-%dT%H:%M:%SZ')
                                for action in actions
                                if action.get('created_at')
                            ]
                            last_action_by_user = max(action_times).replace(
                                tzinfo=pytz.UTC)

                            # if user hasn't commented since they expressed interest, handled this condition
                            # per https://github.com/gitcoinco/web/issues/462#issuecomment-368384384
                            if last_action_by_user.replace() < interest_day_0:
                                last_action_by_user = interest_day_0

                            # some small calcs
                            snooze_time = timezone.timedelta(
                                days=bounty.snooze_warnings_for_days)
                            delta_now_vs_last_action = timezone.now(
                            ) - snooze_time - last_action_by_user
                            last_heard_from_user_days = delta_now_vs_last_action.days

                            # decide action params
                            should_warn_user = last_heard_from_user_days >= num_days_back_to_warn
                            should_delete_interest = last_heard_from_user_days >= num_days_back_to_delete_interest
                            should_ignore = last_heard_from_user_days >= num_days_back_to_ignore_bc_mods_got_it

                            print(
                                f"- its been {last_heard_from_user_days} days since we heard from the user"
                            )
                        if should_ignore:
                            print(
                                f'executing should_ignore for {interest.profile} / {bounty.github_url} '
                            )

                        elif should_delete_interest:
                            print(
                                f'executing should_delete_interest for {interest.profile} / {bounty.github_url} '
                            )
                            interest = interest.mark_for_review()

                            record_user_action_on_interest(
                                interest,
                                'bounty_abandonment_escalation_to_mods',
                                last_heard_from_user_days)

                            # commenting on the GH issue
                            maybe_notify_user_escalated_github(
                                bounty, interest.profile.handle,
                                last_heard_from_user_days)

                            # commenting in slack
                            maybe_notify_bounty_user_escalated_to_slack(
                                bounty, interest.profile.handle,
                                last_heard_from_user_days)

                            # send email
                            bounty_startwork_expired(
                                interest.profile.email, bounty, interest,
                                last_heard_from_user_days)

                        elif should_warn_user:
                            record_user_action_on_interest(
                                interest, 'bounty_abandonment_warning',
                                last_heard_from_user_days)

                            print(
                                f'executing should_warn_user for {interest.profile} / {bounty.github_url} '
                            )

                            # commenting on the GH issue
                            maybe_warn_user_removed_github(
                                bounty, interest.profile.handle,
                                last_heard_from_user_days)

                            # commenting in slack
                            maybe_notify_bounty_user_warned_removed_to_slack(
                                bounty, interest.profile.handle,
                                last_heard_from_user_days)

                            # send email
                            bounty_startwork_expire_warning(
                                interest.profile.email, bounty, interest,
                                last_heard_from_user_days)
                    except Exception as e:
                        print(
                            f'Exception in expiration_start_work.handle(): {e}'
                        )