Ejemplo n.º 1
0
    def handle(self, *args, **options):
        now = timezone.now()
        profile = Profile.objects.filter(handle='gitcoinbot').first()

        bounties = Bounty.objects.current().filter(
            hypercharge_mode=True, hyper_next_publication__lt=now)
        bounties = bounties.exclude(bounty_state__in=['done', 'cancelled'])
        bounties = bounties.order_by('metadata__hyper_tweet_counter')

        if bounties:
            bounty = bounties.first()

            offer_title = f'Work on "{bounty.title}" and receive {floatformat(bounty.value_true)} {bounty.token_name}'
            offer_desc = ''

            event_name = ''
            counter = bounty.metadata['hyper_tweet_counter']
            if counter == 0:
                event_name = 'new_bounty'
                notify_previous_workers(bounty)
                make_secret_offer(profile, offer_title, offer_desc, bounty)
            elif counter == 1:
                event_name = 'remarket_bounty'
            elif counter % 2 == 0:
                make_secret_offer(profile, offer_title, offer_desc, bounty)

            bounty.metadata['hyper_tweet_counter'] += 1
            bounty.hyper_next_publication = now + timedelta(hours=12)
            bounty.save()

            maybe_market_to_twitter(bounty, event_name)
Ejemplo n.º 2
0
def create_new_interest_helper(bounty, user):
    profile_id = user.profile.pk
    interest = Interest.objects.create(profile_id=profile_id)
    bounty.interested.add(interest)
    record_user_action(user, 'start_work', interest)
    maybe_market_to_slack(bounty, 'start_work')
    maybe_market_to_twitter(bounty, 'start_work')
    return interest
Ejemplo n.º 3
0
def remove_interest(request, bounty_id):
    """Unclaim work from the Bounty.

    Can only be called by someone who has started work

    :request method: POST

    post_id (int): ID of the Bounty.

    Returns:
        dict: The success key with a boolean value and accompanying error.

    """
    profile_id = request.user.profile.pk if request.user.is_authenticated and hasattr(request.user, 'profile') else None

    access_token = request.GET.get('token')
    if access_token:
        helper_handle_access_token(request, access_token)
        github_user_data = get_github_user_data(access_token)
        profile = Profile.objects.filter(handle=github_user_data['login']).first()
        profile_id = profile.pk

    if not profile_id:
        return JsonResponse(
            {'error': _('You must be authenticated via github to use this feature!')},
            status=401)

    try:
        bounty = Bounty.objects.get(pk=bounty_id)
    except Bounty.DoesNotExist:
        return JsonResponse({'errors': ['Bounty doesn\'t exist!']},
                            status=401)

    try:
        interest = Interest.objects.get(profile_id=profile_id, bounty=bounty)
        record_user_action(request.user, 'stop_work', interest)
        bounty.interested.remove(interest)
        interest.delete()
        maybe_market_to_slack(bounty, 'stop_work')
        maybe_market_to_user_slack(bounty, 'stop_work')
        maybe_market_to_twitter(bounty, 'stop_work')
    except Interest.DoesNotExist:
        return JsonResponse({
            'errors': [_('You 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()

    return JsonResponse({'success': True})
Ejemplo n.º 4
0
def remove_interest(request, bounty_id):
    """Unclaim work from the Bounty.

    :request method: POST

    post_id (int): ID of the Bounty.

    Returns:
        dict: The success key with a boolean value and accompanying error.

    """
    access_token = request.GET.get('token')
    if access_token and is_github_token_valid(access_token):
        helper_handle_access_token(request, access_token)

    profile_id = request.session.get('profile_id')
    if not profile_id:
        return JsonResponse(
            {
                'error':
                'You must be authenticated via github to use this feature!'
            },
            status=401)

    try:
        bounty = Bounty.objects.get(pk=bounty_id)
    except Bounty.DoesNotExist:
        return JsonResponse({'errors': ['Bounty doesn\'t exist!']}, status=401)

    try:
        interest = Interest.objects.get(profile_id=profile_id, bounty=bounty)
        record_user_action(
            Profile.objects.get(pk=profile_id).handle, 'stop_work', interest)
        bounty.interested.remove(interest)
        interest.delete()
        maybe_market_to_slack(bounty, 'stop_work')
        maybe_market_to_twitter(bounty, 'stop_work')
    except Interest.DoesNotExist:
        return JsonResponse(
            {
                'errors': ['You 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()

    return JsonResponse({'success': True})
Ejemplo n.º 5
0
def process_bounty_changes(old_bounty, new_bounty):
    """Process legacy bounty changes.

    Args:
        old_bounty (dashboard.models.Bounty): The old Bounty object.
        new_bounty (dashboard.models.Bounty): The new Bounty object.

    """
    # process bounty sync requests
    did_bsr = False
    for bsr in BountySyncRequest.objects.filter(processed=False, github_url=new_bounty.github_url):
        did_bsr = True
        bsr.processed = True
        bsr.save()

    # new bounty
    if (not old_bounty and new_bounty and new_bounty.is_open) or (not old_bounty.is_open and new_bounty.is_open):
        event_name = 'new_bounty'
    elif old_bounty.num_fulfillments < new_bounty.num_fulfillments:
        event_name = 'work_submitted'
    elif old_bounty.is_open and not new_bounty.is_open:
        if new_bounty.status == 'cancelled':
            event_name = 'killed_bounty'
        else:
            event_name = 'work_done'
    else:
        event_name = 'unknown_event'
    print(event_name)

    # Build profile pairs list
    if new_bounty.fulfillments.exists():
        profile_pairs = build_profile_pairs(new_bounty)

    # marketing
    if event_name != 'unknown_event':
        print("============ posting ==============")
        did_post_to_twitter = maybe_market_to_twitter(new_bounty, event_name)
        did_post_to_slack = maybe_market_to_slack(new_bounty, event_name)
        did_post_to_github = maybe_market_to_github(new_bounty, event_name, profile_pairs)
        did_post_to_email = maybe_market_to_email(new_bounty, event_name)
        print("============ done posting ==============")

        # what happened
        what_happened = {
            'did_bsr': did_bsr,
            'did_post_to_email': did_post_to_email,
            'did_post_to_github': did_post_to_github,
            'did_post_to_slack': did_post_to_slack,
            'did_post_to_twitter': did_post_to_twitter,
        }

        print("Legacy changes processed: ")
        pp = pprint.PrettyPrinter(indent=4)
        pp.pprint(what_happened)
    else:
        print('No notifications sent - Legacy Event Type Unknown = did_bsr: ', did_bsr)
Ejemplo n.º 6
0
 def handle(self, *args, **options):
     bounties = Bounty.objects.filter(current_bounty=True,
                                      network='mainnet',
                                      idx_status='open')
     if bounties.count() < 3:
         print('count is only {}. exiting'.format(bounties.count()))
         return
     bounty = bounties.order_by('?').first()
     print(bounty)
     did_tweet = maybe_market_to_twitter(bounty, 'remarket_bounty', '0x0')
     print(did_tweet)
Ejemplo n.º 7
0
def process_bounty_changes(old_bounty, new_bounty, txid):
    from dashboard.utils import build_profile_pairs
    profile_pairs = None
    # process bounty sync requests
    did_bsr = False
    for bsr in BountySyncRequest.objects.filter(
            processed=False, github_url=new_bounty.github_url):
        did_bsr = True
        bsr.processed = True
        bsr.save()

    # new bounty
    if (old_bounty is None and new_bounty
            and new_bounty.is_open) or (not old_bounty.is_open
                                        and new_bounty.is_open):
        event_name = 'new_bounty'
    elif old_bounty.num_fulfillments < new_bounty.num_fulfillments:
        event_name = 'work_submitted'
    elif old_bounty.is_open and not new_bounty.is_open:
        if new_bounty.status == 'cancelled':
            event_name = 'killed_bounty'
        else:
            event_name = 'work_done'
    else:
        event_name = 'unknown_event'
    print(event_name)

    # Build profile pairs list
    if new_bounty.fulfillments.exists():
        profile_pairs = build_profile_pairs(new_bounty)

    # marketing
    print("============ posting ==============")
    did_post_to_twitter = maybe_market_to_twitter(new_bounty, event_name)
    did_post_to_slack = maybe_market_to_slack(new_bounty, event_name)
    did_post_to_github = maybe_market_to_github(new_bounty, event_name,
                                                profile_pairs)
    did_post_to_email = maybe_market_to_email(new_bounty, event_name)
    print("============ done posting ==============")

    # what happened
    what_happened = {
        'did_bsr': did_bsr,
        'did_post_to_email': did_post_to_email,
        'did_post_to_github': did_post_to_github,
        'did_post_to_slack': did_post_to_slack,
        'did_post_to_twitter': did_post_to_twitter,
    }

    print("changes processed: ")
    pp = pprint.PrettyPrinter(indent=4)
    pp.pprint(what_happened)
Ejemplo n.º 8
0
 def handle(self, *args, **options):
     return  # per 2018/01/22 convo with vivek / kevin, these tweets have low engagement
     # we are going to test manually promoting these tweets for a week and come back to revisit this
     bounties = Bounty.objects.filter(current_bounty=True,
                                      network='mainnet',
                                      idx_status='open')
     if bounties.count() < 3:
         print('count is only {}. exiting'.format(bounties.count()))
         return
     bounty = bounties.order_by('?').first()
     print(bounty)
     did_tweet = maybe_market_to_twitter(bounty, 'remarket_bounty', '0x0')
     print(did_tweet)
Ejemplo n.º 9
0
def process_bounty_changes(old_bounty, new_bounty, txid):

    # process bounty sync requests
    did_bsr = False
    for bsr in BountySyncRequest.objects.filter(
            processed=False, github_url=new_bounty.github_url):
        did_bsr = True
        bsr.processed = True
        bsr.save()

    # new bounty
    null_address = '0x0000000000000000000000000000000000000000'
    if (old_bounty is None and new_bounty
            and new_bounty.is_open) or (not old_bounty.is_open
                                        and new_bounty.is_open):
        event_name = 'new_bounty'
    elif old_bounty.fulfiller_address == null_address and new_bounty.fulfiller_address != null_address:
        event_name = 'work_submitted'
    elif old_bounty.is_open and not new_bounty.is_open:
        if new_bounty.status == 'cancelled':
            event_name = 'killed_bounty'
        else:
            event_name = 'work_done'
    elif old_bounty.fulfiller_address != null_address and new_bounty.fulfiller_address == null_address:
        event_name = 'rejected_claim'
    else:
        event_name = 'unknown_event'
    print(event_name)

    # marketing
    print("============ posting ==============")
    did_post_to_twitter = maybe_market_to_twitter(new_bounty, event_name)
    did_post_to_slack = maybe_market_to_slack(new_bounty, event_name)
    did_post_to_github = maybe_market_to_github(new_bounty, event_name)
    did_post_to_email = maybe_market_to_email(new_bounty, event_name)
    print("============ done posting ==============")

    # what happened
    what_happened = {
        'did_bsr': did_bsr,
        'did_post_to_email': did_post_to_email,
        'did_post_to_github': did_post_to_github,
        'did_post_to_slack': did_post_to_slack,
        'did_post_to_twitter': did_post_to_twitter,
    }

    print("changes processed: ")
    pp = pprint.PrettyPrinter(indent=4)
    pp.pprint(what_happened)
Ejemplo n.º 10
0
    def handle(self, *args, **options):
        bounties = Bounty.objects.current().filter(
            network='mainnet',
            idx_status='open')
        if bounties.count() < 3:
            print('count is only {}. exiting'.format(bounties.count()))
            return
        bounty = bounties.order_by('?').first()

        remarket_bounties = bounties.filter(admin_mark_as_remarket_ready=True)
        if remarket_bounties.exists():
            bounty = remarket_bounties.order_by('?').first()

        print(bounty)
        did_tweet = maybe_market_to_twitter(bounty, 'remarket_bounty')
        did_slack = maybe_market_to_slack(bounty, 'this funded issue could use some action!')
        print("did tweet", did_tweet)
        print("did slack", did_slack)
Ejemplo n.º 11
0
def process_bounty_changes(old_bounty, new_bounty):
    """Process Bounty changes.

    Args:
        old_bounty (dashboard.models.Bounty): The old Bounty object.
        new_bounty (dashboard.models.Bounty): The new Bounty object.

    """
    from dashboard.utils import build_profile_pairs
    profile_pairs = None
    # process bounty sync requests
    did_bsr = False
    for bsr in BountySyncRequest.objects.filter(
            processed=False, github_url=new_bounty.github_url).nocache():
        did_bsr = True
        bsr.processed = True
        bsr.save()

    # get json diff
    json_diff = diff(old_bounty.raw_data, new_bounty.raw_data) if (
        old_bounty and new_bounty) else None

    # new bounty
    if not old_bounty or (not old_bounty and new_bounty
                          and new_bounty.is_open) or (not old_bounty.is_open
                                                      and new_bounty
                                                      and new_bounty.is_open):
        is_greater_than_x_days_old = new_bounty.web3_created < (
            timezone.now() - timezone.timedelta(hours=24))
        if is_greater_than_x_days_old and not settings.IS_DEBUG_ENV:
            msg = f"attempting to create a new bounty ({new_bounty.standard_bounties_id}) when is_greater_than_x_days_old = True"
            print(msg)
            raise Exception(msg)
        event_name = 'new_bounty'
    elif old_bounty.num_fulfillments < new_bounty.num_fulfillments:
        event_name = 'work_submitted'
    elif old_bounty.is_open and not new_bounty.is_open:
        if new_bounty.status in ['cancelled', 'expired']:
            event_name = 'killed_bounty'
        else:
            event_name = 'work_done'
    elif old_bounty.value_in_token < new_bounty.value_in_token:
        event_name = 'increased_bounty'
    else:
        event_name = 'unknown_event'
        logger.info(
            f'got an unknown event from bounty {old_bounty.pk} => {new_bounty.pk}: {json_diff}'
        )

    print(f"- {event_name} event; diff => {json_diff}")

    # record a useraction for this
    record_user_action(event_name, old_bounty, new_bounty)
    record_bounty_activity(event_name, old_bounty, new_bounty)

    # Build profile pairs list
    if new_bounty.fulfillments.exists():
        profile_pairs = build_profile_pairs(new_bounty)

    # marketing
    if event_name != 'unknown_event':
        print("============ posting ==============")
        did_post_to_twitter = maybe_market_to_twitter(new_bounty, event_name)
        did_post_to_slack = maybe_market_to_slack(new_bounty, event_name)
        did_post_to_user_slack = maybe_market_to_user_slack(
            new_bounty, event_name)
        did_post_to_user_discord = maybe_market_to_user_discord(
            new_bounty, event_name)
        did_post_to_github = maybe_market_to_github(new_bounty, event_name,
                                                    profile_pairs)
        did_post_to_email = maybe_market_to_email(new_bounty, event_name)
        print("============ done posting ==============")

        # what happened
        what_happened = {
            'did_bsr': did_bsr,
            'did_post_to_email': did_post_to_email,
            'did_post_to_github': did_post_to_github,
            'did_post_to_slack': did_post_to_slack,
            'did_post_to_user_slack': did_post_to_user_slack,
            'did_post_to_user_discord': did_post_to_user_discord,
            'did_post_to_twitter': did_post_to_twitter,
        }

        print("changes processed: ")
        pp = pprint.PrettyPrinter(indent=4)
        pp.pprint(what_happened)
    else:
        print('No notifications sent - Event Type Unknown = did_bsr: ',
              did_bsr)
Ejemplo n.º 12
0
def new_interest(request, bounty_id):
    """Claim Work for a Bounty.

    :request method: POST

    Args:
        post_id (int): ID of the Bounty.

    Returns:
        dict: The success key with a boolean value and accompanying error.

    """
    access_token = request.GET.get('token')
    if access_token and is_github_token_valid(access_token):
        helper_handle_access_token(request, access_token)

    profile_id = request.session.get('profile_id')
    if not profile_id:
        return JsonResponse(
            {
                'error':
                'You must be authenticated via github to use this feature!'
            },
            status=401)

    try:
        bounty = Bounty.objects.get(pk=bounty_id)
    except Bounty.DoesNotExist:
        raise Http404

    num_issues = 3
    active_bounties = Bounty.objects.current().filter(
        idx_status__in=['open', 'started'])
    num_active = Interest.objects.filter(profile_id=profile_id,
                                         bounty__in=active_bounties).count()
    is_working_on_too_much_stuff = num_active >= num_issues
    if is_working_on_too_much_stuff:
        return JsonResponse(
            {
                'error':
                f'You may only work on max of {num_issues} issues at once.',
                'success': False
            },
            status=401)

    try:
        Interest.objects.get(profile_id=profile_id, bounty=bounty)
        return JsonResponse(
            {
                'error': 'You have already expressed interest in this bounty!',
                'success': False
            },
            status=401)
    except Interest.DoesNotExist:
        interest = Interest.objects.create(profile_id=profile_id)
        bounty.interested.add(interest)
        record_user_action(
            Profile.objects.get(pk=profile_id).handle, 'start_work', interest)
        maybe_market_to_slack(bounty, 'start_work')
        maybe_market_to_twitter(bounty, 'start_work')
    except Interest.MultipleObjectsReturned:
        bounty_ids = bounty.interested \
            .filter(profile_id=profile_id) \
            .values_list('id', flat=True) \
            .order_by('-created')[1:]

        Interest.objects.filter(pk__in=list(bounty_ids)).delete()

        return JsonResponse(
            {
                'error': 'You have already expressed interest in this bounty!',
                'success': False
            },
            status=401)

    return JsonResponse({
        'success': True,
        'profile': ProfileSerializer(interest.profile).data
    })