Example #1
0
def grant_details(request, grant_id, grant_slug):
    """Display the Grant details page."""
    profile = get_profile(request)

    try:
        grant = Grant.objects.prefetch_related('subscriptions', 'milestones',
                                               'updates').get(pk=grant_id,
                                                              slug=grant_slug)
        milestones = grant.milestones.order_by('due_date')
        updates = grant.updates.order_by('-created_on')
        subscriptions = grant.subscriptions.filter(active=True, error=False)
        cancelled_subscriptions = grant.subscriptions.filter(
            Q(active=False, error=False) | Q(error=True))
        contributions = Contribution.objects.filter(
            subscription__in=grant.subscriptions.all())
        user_subscription = grant.subscriptions.filter(
            contributor_profile=profile, active=True).first()
    except Grant.DoesNotExist:
        raise Http404

    if request.method == 'POST' and (profile == grant.admin_profile
                                     or request.user.is_staff):
        if request.FILES.get('input_image'):
            logo = request.FILES.get('input_image', None)
            grant.logo = logo
            grant.save()
            return redirect(
                reverse('grants:details', args=(grant.pk, grant.slug)))
        if 'contract_address' in request.POST:
            grant.cancel_tx_id = request.POST.get('grant_cancel_tx_id', '')
            grant.active = False
            grant.save()
            grant_cancellation(grant, user_subscription)
            for sub in subscriptions:
                subscription_terminated(grant, sub)
        elif 'input-title' in request.POST:
            update_kwargs = {
                'title': request.POST.get('input-title', ''),
                'description': request.POST.get('description', ''),
                'grant': grant
            }
            Update.objects.create(**update_kwargs)
        elif 'contract_owner_address' in request.POST:
            grant.contract_owner_address = request.POST.get(
                'contract_owner_address')
            grant.save()
            return redirect(
                reverse('grants:details', args=(grant.pk, grant.slug)))
        elif 'edit-title' in request.POST:
            grant.title = request.POST.get('edit-title')
            grant.reference_url = request.POST.get('edit-reference_url')
            form_profile = request.POST.get('edit-admin_profile')
            admin_profile = Profile.objects.get(handle=form_profile)
            grant.description = request.POST.get('edit-description')
            grant.amount_goal = Decimal(request.POST.get('edit-amount_goal'))
            team_members = request.POST.getlist('edit-grant_members[]')
            team_members.append(str(admin_profile.id))
            grant.team_members.set(team_members)
            if grant.admin_profile != admin_profile:
                grant.request_ownership_change = admin_profile
                change_grant_owner_request(grant,
                                           grant.request_ownership_change)
            grant.save()
            return redirect(
                reverse('grants:details', args=(grant.pk, grant.slug)))

    params = {
        'active':
        'grant_details',
        'grant':
        grant,
        'title':
        grant.title,
        'card_desc':
        grant.description,
        'avatar_url':
        grant.logo.url if grant.logo else None,
        'subscriptions':
        subscriptions,
        'cancelled_subscriptions':
        cancelled_subscriptions,
        'contributions':
        contributions,
        'user_subscription':
        user_subscription,
        'is_admin': (grant.admin_profile.id == profile.id)
        if profile and grant.admin_profile else False,
        'grant_is_inactive':
        not grant.active,
        'updates':
        updates,
        'milestones':
        milestones,
        'keywords':
        get_keywords(),
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(4),
        'recommend_gas_price_slow':
        recommend_min_gas_price_to_confirm_in_time(120),
        'recommend_gas_price_avg':
        recommend_min_gas_price_to_confirm_in_time(15),
        'recommend_gas_price_fast':
        recommend_min_gas_price_to_confirm_in_time(1),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
        'gas_advisories':
        gas_advisories(),
    }

    if request.method == 'GET' and grant.request_ownership_change and profile == grant.request_ownership_change:
        if request.GET.get('ownership', None) == 'accept':
            previous_owner = grant.admin_profile
            grant.admin_profile = grant.request_ownership_change
            grant.request_ownership_change = None
            grant.save()
            change_grant_owner_accept(grant, grant.admin_profile,
                                      previous_owner)
            params['change_ownership'] = 'Y'
        elif request.GET.get('ownership', None) == 'reject':
            grant.request_ownership_change = None
            grant.save()
            change_grant_owner_reject(grant, grant.admin_profile)
            params['change_ownership'] = 'N'

    return TemplateResponse(request, 'grants/detail/index.html', params)
Example #2
0
def grant_new(request):
    """Handle new grant."""
    if not request.user.has_perm('grants.add_grant'):
        return redirect('https://consensys1mac.typeform.com/to/HFcZKe/')

    profile = get_profile(request)

    if request.method == 'POST':
        if 'title' in request.POST:
            logo = request.FILES.get('input_image', None)
            receipt = json.loads(request.POST.get('receipt', '{}'))
            team_members = request.POST.getlist('team_members[]')

            grant_kwargs = {
                'title':
                request.POST.get('title', ''),
                'description':
                request.POST.get('description', ''),
                'reference_url':
                request.POST.get('reference_url', ''),
                'admin_address':
                request.POST.get('admin_address', ''),
                'contract_owner_address':
                request.POST.get('contract_owner_address', ''),
                'token_address':
                request.POST.get('token_address', ''),
                'token_symbol':
                request.POST.get('token_symbol', ''),
                'amount_goal':
                request.POST.get('amount_goal', 1),
                'contract_version':
                request.POST.get('contract_version', ''),
                'deploy_tx_id':
                request.POST.get('transaction_hash', ''),
                'network':
                request.POST.get('network', 'mainnet'),
                'metadata':
                receipt,
                'admin_profile':
                profile,
                'logo':
                logo,
            }
            grant = Grant.objects.create(**grant_kwargs)
            team_members.append(profile.id)
            grant.team_members.add(*list(
                filter(lambda member_id: member_id > 0, map(int,
                                                            team_members))))
            return JsonResponse({
                'success': True,
            })

        if 'contract_address' in request.POST:
            tx_hash = request.POST.get('transaction_hash', '')
            grant = Grant.objects.filter(deploy_tx_id=tx_hash).first()
            grant.contract_address = request.POST.get('contract_address', '')
            grant.save()
            new_grant(grant, profile)
            return JsonResponse({
                'success':
                True,
                'url':
                reverse('grants:details', args=(grant.pk, grant.slug))
            })

    params = {
        'active':
        'new_grant',
        'title':
        _('New Grant'),
        'card_desc':
        _('Provide sustainable funding for Open Source with Gitcoin Grants'),
        'profile':
        profile,
        'grant': {},
        'keywords':
        get_keywords(),
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(4),
        'recommend_gas_price_slow':
        recommend_min_gas_price_to_confirm_in_time(120),
        'recommend_gas_price_avg':
        recommend_min_gas_price_to_confirm_in_time(15),
        'recommend_gas_price_fast':
        recommend_min_gas_price_to_confirm_in_time(1),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
        'gas_advisories':
        gas_advisories(),
    }

    return TemplateResponse(request, 'grants/new.html', params)
Example #3
0
def subscription_cancel(request, grant_id, grant_slug, subscription_id):
    """Handle the cancellation of a grant subscription."""
    subscription = Subscription.objects.select_related('grant').get(
        pk=subscription_id)
    grant = getattr(subscription, 'grant', None)
    now = datetime.datetime.now()
    profile = get_profile(request)

    if not subscription.active:
        params = {
            'active': 'grant_error',
            'title': _('Grant Subscription Cancelled'),
            'grant': grant
        }

        if grant.active:
            params['text'] = _(
                'This Grant subscription has already been cancelled.')
        else:
            params['text'] = _(
                'This Subscription is already cancelled as the grant is not longer active.'
            )

        return TemplateResponse(request, 'grants/shared/error.html', params)

    if request.method == 'POST' and (
            profile == subscription.contributor_profile
            or request.user.has_perm('grants.change_subscription')):
        subscription.end_approve_tx_id = request.POST.get(
            'sub_end_approve_tx_id', '')
        subscription.cancel_tx_id = request.POST.get('sub_cancel_tx_id', '')
        subscription.active = False
        subscription.save()
        record_subscription_activity_helper('killed_grant_contribution',
                                            subscription, profile)

        value_usdt = subscription.get_converted_amount()
        if value_usdt:
            grant.monthly_amount_subscribed -= subscription.get_converted_monthly_amount(
            )

        grant.save()
        support_cancellation(grant, subscription)
        messages.info(
            request,
            _('Your subscription has been canceled. We hope you continue to support other open source projects!'
              ))
        return redirect(reverse('grants:details', args=(grant.pk, grant.slug)))

    params = {
        'active':
        'cancel_grant',
        'title':
        _('Cancel Grant Subscription'),
        'card_desc':
        _('Provide sustainable funding for Open Source with Gitcoin Grants'),
        'subscription':
        subscription,
        'grant':
        grant,
        'now':
        now,
        'keywords':
        get_keywords(),
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(4),
        'recommend_gas_price_slow':
        recommend_min_gas_price_to_confirm_in_time(120),
        'recommend_gas_price_avg':
        recommend_min_gas_price_to_confirm_in_time(15),
        'recommend_gas_price_fast':
        recommend_min_gas_price_to_confirm_in_time(1),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
        'gas_advisories':
        gas_advisories(),
    }

    return TemplateResponse(request, 'grants/cancel.html', params)
Example #4
0
 def test_conf_time_spread(self):
     """Test the gas util conf_time_spread method."""
     assert conf_time_spread(
     ) == '[["1.00", "10.00"], ["2.00", "4.00"], ["3.00", "1.00"]]'
Example #5
0
def grant_new_v0(request):
    """Create a v0 version of a grant contract."""
    profile = get_profile(request)

    if request.method == 'POST':
        if 'title' in request.POST:
            logo = request.FILES.get('input_image', None)
            receipt = json.loads(request.POST.get('receipt', '{}'))
            team_members = request.POST.getlist('team_members[]')

            grant_kwargs = {
                'title':
                request.POST.get('title', ''),
                'description':
                request.POST.get('description', ''),
                'reference_url':
                request.POST.get('reference_url', ''),
                'admin_address':
                request.POST.get('admin_address', ''),
                'contract_owner_address':
                request.POST.get('contract_owner_address', ''),
                'token_address':
                request.POST.get('token_address', ''),
                'token_symbol':
                request.POST.get('token_symbol', ''),
                'amount_goal':
                request.POST.get('amount_goal', 1),
                'contract_version':
                request.POST.get('contract_version', ''),
                'deploy_tx_id':
                request.POST.get('transaction_hash', ''),
                'network':
                request.POST.get('network', 'mainnet'),
                'metadata':
                receipt,
                'admin_profile':
                profile,
                'logo':
                logo,
            }
            grant = Grant.objects.create(**grant_kwargs)

            team_members = (team_members[0].split(','))
            team_members.append(profile.id)
            team_members = list(set(team_members))

            for i in range(0, len(team_members)):
                team_members[i] = int(team_members[i])

            grant.team_members.add(*team_members)
            grant.save()

            return JsonResponse({
                'success': True,
            })

        if 'contract_address' in request.POST:
            tx_hash = request.POST.get('transaction_hash', '')
            if not tx_hash:
                return JsonResponse({
                    'success': False,
                    'info': 'no tx hash',
                    'url': None,
                })

            grant = Grant.objects.filter(deploy_tx_id=tx_hash).first()
            grant.contract_address = request.POST.get('contract_address', '')
            print(tx_hash, grant.contract_address)
            grant.save()
            record_grant_activity_helper('new_grant', grant, profile)
            new_grant(grant, profile)
            return JsonResponse({
                'success':
                True,
                'url':
                reverse('grants:details', args=(grant.pk, grant.slug))
            })

    params = {
        'active':
        'new_grant',
        'title':
        _('New Grant'),
        'card_desc':
        _('Provide sustainable funding for Open Source with Gitcoin Grants'),
        'profile':
        profile,
        'grant': {},
        'keywords':
        get_keywords(),
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(4),
        'recommend_gas_price_slow':
        recommend_min_gas_price_to_confirm_in_time(120),
        'recommend_gas_price_avg':
        recommend_min_gas_price_to_confirm_in_time(15),
        'recommend_gas_price_fast':
        recommend_min_gas_price_to_confirm_in_time(1),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
        'gas_advisories':
        gas_advisories(),
        'trusted_relayer':
        settings.GRANTS_OWNER_ACCOUNT
    }

    return TemplateResponse(request, 'grants/newv0.html', params)
Example #6
0
def grant_fund(request, grant_id, grant_slug):
    """Handle grant funding."""
    try:
        grant = Grant.objects.get(pk=grant_id, slug=grant_slug)
    except Grant.DoesNotExist:
        raise Http404

    profile = get_profile(request)

    if not grant.active:
        params = {
            'active': 'grant_error',
            'title': _('Grant Ended'),
            'grant': grant,
            'text': _('This Grant is not longer active.')
        }
        return TemplateResponse(request, 'grants/shared/error.html', params)

    active_subscription = Subscription.objects.select_related('grant').filter(
        grant=grant_id,
        active=True,
        error=False,
        contributor_profile=request.user.profile)

    if active_subscription:
        params = {
            'active': 'grant_error',
            'title': _('Subscription Exists'),
            'grant': grant,
            'text':
            _('You already have an active subscription for this grant.')
        }
        return TemplateResponse(request, 'grants/shared/error.html', params)

    if grant.contract_address == '0x0':
        messages.info(
            request,
            _('This grant is not configured to accept funding at this time.  Please contact [email protected] if you believe this message is in error!'
              ))
        logger.error(
            f"Grant {grant.pk} is not properly configured for funding.  Please set grant.contract_address on this grant"
        )
        return redirect(reverse('grants:details', args=(grant.pk, grant.slug)))

    if request.method == 'POST':
        if 'contributor_address' in request.POST:
            subscription = Subscription()

            subscription.active = False
            subscription.contributor_address = request.POST.get(
                'contributor_address', '')
            subscription.amount_per_period = request.POST.get(
                'amount_per_period', 0)
            subscription.real_period_seconds = request.POST.get(
                'real_period_seconds', 2592000)
            subscription.frequency = request.POST.get('frequency', 30)
            subscription.frequency_unit = request.POST.get(
                'frequency_unit', 'days')
            subscription.token_address = request.POST.get('token_address', '')
            subscription.token_symbol = request.POST.get('token_symbol', '')
            subscription.gas_price = request.POST.get('gas_price', 0)
            subscription.new_approve_tx_id = request.POST.get(
                'sub_new_approve_tx_id', '0x0')
            subscription.num_tx_approved = request.POST.get(
                'num_tx_approved', 1)
            subscription.network = request.POST.get('network', '')
            subscription.contributor_profile = profile
            subscription.grant = grant
            subscription.save()

            # one time payments
            if int(subscription.num_tx_approved) == 1:
                subscription.successful_contribution(
                    subscription.new_approve_tx_id)
                subscription.error = True  #cancel subs so it doesnt try to bill again
                subscription.subminer_comments = "skipping subminer bc this is a 1 and done subscription, and tokens were alredy sent"
                subscription.save()
                record_subscription_activity_helper('new_grant_contribution',
                                                    subscription, profile)
            else:
                record_subscription_activity_helper('new_grant_subscription',
                                                    subscription, profile)

            # TODO - how do we attach the tweet modal WITH BULK TRANSFER COUPON next pageload??
            messages.info(
                request,
                _('Your subscription has been created. It will bill within the next 5 minutes or so. Thank you for supporting Open Source !'
                  ))

            return JsonResponse({
                'success': True,
            })

        if 'hide_wallet_address' in request.POST:
            profile.hide_wallet_address = bool(
                request.POST.get('hide_wallet_address', False))
            profile.save()

        if 'signature' in request.POST:
            sub_new_approve_tx_id = request.POST.get('sub_new_approve_tx_id',
                                                     '')
            subscription = Subscription.objects.filter(
                new_approve_tx_id=sub_new_approve_tx_id).first()
            subscription.active = True
            subscription.subscription_hash = request.POST.get(
                'subscription_hash', '')
            subscription.contributor_signature = request.POST.get(
                'signature', '')
            if 'split_tx_id' in request.POST:
                subscription.split_tx_id = request.POST.get('split_tx_id', '')
                subscription.save_split_tx_to_contribution()
            if 'split_tx_confirmed' in request.POST:
                subscription.split_tx_confirmed = bool(
                    request.POST.get('split_tx_confirmed', False))
                subscription.save_split_tx_to_contribution()
            subscription.save()

            value_usdt = subscription.get_converted_amount()
            if value_usdt:
                grant.monthly_amount_subscribed += subscription.get_converted_monthly_amount(
                )

            grant.save()
            new_supporter(grant, subscription)
            thank_you_for_supporting(grant, subscription)
            return JsonResponse({
                'success':
                True,
                'url':
                reverse('grants:details', args=(grant.pk, grant.slug))
            })

    splitter_contract_address = settings.SPLITTER_CONTRACT_ADDRESS

    # handle phantom funding
    active_tab = 'normal'
    fund_reward = None
    round_number = 4
    can_phantom_fund = request.user.is_authenticated and request.user.groups.filter(
        name='phantom_funders').exists()
    phantom_funds = PhantomFunding.objects.filter(
        profile=request.user.profile,
        round_number=round_number).order_by('created_on').nocache(
        ) if request.user.is_authenticated else PhantomFunding.objects.none()
    is_phantom_funding_this_grant = can_phantom_fund and phantom_funds.filter(
        grant=grant).exists()
    show_tweet_modal = False
    if can_phantom_fund:
        active_tab = 'phantom'
    if can_phantom_fund and request.POST.get('toggle_phantom_fund'):
        if is_phantom_funding_this_grant:
            msg = "You are no longer signaling for this grant."
            phantom_funds.filter(grant=grant).delete()
        else:
            msg = "You are now signaling for this grant."
            show_tweet_modal = True
            name_search = 'grants_round_4_contributor' if not settings.DEBUG else 'pogs_eth'
            fund_reward = BulkTransferCoupon.objects.filter(
                token__name__contains=name_search).order_by('?').first()
            PhantomFunding.objects.create(grant=grant,
                                          profile=request.user.profile,
                                          round_number=round_number)
        messages.info(request, msg)
        is_phantom_funding_this_grant = not is_phantom_funding_this_grant

    params = {
        'profile':
        profile,
        'active':
        'fund_grant',
        'title':
        _('Fund Grant'),
        'card_desc':
        _('Provide sustainable funding for Open Source with Gitcoin Grants'),
        'subscription': {},
        'show_tweet_modal':
        show_tweet_modal,
        'grant_has_no_token':
        True if grant.token_address
        == '0x0000000000000000000000000000000000000000' else False,
        'grant':
        grant,
        'clr_prediction_curve':
        [c[1]
         for c in grant.clr_prediction_curve] if grant.clr_prediction_curve
        and len(grant.clr_prediction_curve[0]) > 1 else [0, 0, 0, 0, 0, 0],
        'keywords':
        get_keywords(),
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(4),
        'recommend_gas_price_slow':
        recommend_min_gas_price_to_confirm_in_time(120),
        'recommend_gas_price_avg':
        recommend_min_gas_price_to_confirm_in_time(15),
        'recommend_gas_price_fast':
        recommend_min_gas_price_to_confirm_in_time(1),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
        'gas_advisories':
        gas_advisories(),
        'splitter_contract_address':
        settings.SPLITTER_CONTRACT_ADDRESS,
        'gitcoin_donation_address':
        settings.GITCOIN_DONATION_ADDRESS,
        'can_phantom_fund':
        can_phantom_fund,
        'is_phantom_funding_this_grant':
        is_phantom_funding_this_grant,
        'active_tab':
        active_tab,
        'fund_reward':
        fund_reward,
        'phantom_funds':
        phantom_funds,
        'clr_round':
        clr_round,
        'total_clr_pot':
        total_clr_pot,
        'clr_active':
        True
    }
    return TemplateResponse(request, 'grants/fund.html', params)
Example #7
0
def grant_details(request, grant_id, grant_slug):
    """Display the Grant details page."""
    profile = get_profile(request)
    add_cancel_params = False
    try:
        grant = Grant.objects.prefetch_related('subscriptions', 'milestones',
                                               'updates').get(pk=grant_id,
                                                              slug=grant_slug)
        milestones = grant.milestones.order_by('due_date')
        updates = grant.updates.order_by('-created_on')
        subscriptions = grant.subscriptions.filter(
            active=True, error=False).order_by('-created_on')
        cancelled_subscriptions = grant.subscriptions.filter(
            active=False, error=False).order_by('-created_on')
        _contributions = Contribution.objects.filter(
            subscription__in=grant.subscriptions.all())
        phantom_funds = grant.phantom_funding.all()
        contributions = list(_contributions.order_by('-created_on')) + [
            ele.to_mock_contribution()
            for ele in phantom_funds.order_by('-created_on')
        ]
        contributors = list(
            _contributions.distinct('subscription__contributor_profile')
        ) + list(phantom_funds.distinct('profile'))
        activity_count = len(cancelled_subscriptions) + len(contributions)
        user_subscription = grant.subscriptions.filter(
            contributor_profile=profile, active=True).first()
        user_non_errored_subscription = grant.subscriptions.filter(
            contributor_profile=profile, active=True, error=False).first()
        add_cancel_params = user_subscription
    except Grant.DoesNotExist:
        raise Http404

    is_admin = (grant.admin_profile.id
                == profile.id) if profile and grant.admin_profile else False
    if is_admin:
        add_cancel_params = True

    is_team_member = False
    if profile:
        for team_member in grant.team_members.all():
            if team_member.id == profile.id:
                is_team_member = True
                break

    if request.method == 'POST' and (is_team_member or request.user.is_staff):
        if request.FILES.get('input_image'):
            logo = request.FILES.get('input_image', None)
            grant.logo = logo
            grant.save()
            record_grant_activity_helper('update_grant', grant, profile)
            return redirect(
                reverse('grants:details', args=(grant.pk, grant.slug)))
        if 'contract_address' in request.POST:
            grant.cancel_tx_id = request.POST.get('grant_cancel_tx_id', '')
            grant.active = False
            grant.save()
            grant_cancellation(grant, user_subscription)
            for sub in subscriptions:
                subscription_terminated(grant, sub)
            record_grant_activity_helper('killed_grant', grant, profile)
        elif 'input-title' in request.POST:
            update_kwargs = {
                'title': request.POST.get('input-title', ''),
                'description': request.POST.get('description', ''),
                'grant': grant
            }
            Update.objects.create(**update_kwargs)
            record_grant_activity_helper('update_grant', grant, profile)
        elif 'edit-title' in request.POST:
            grant.title = request.POST.get('edit-title')
            grant.reference_url = request.POST.get('edit-reference_url')
            grant.amount_goal = Decimal(request.POST.get('edit-amount_goal'))
            team_members = request.POST.getlist('edit-grant_members[]')
            team_members.append(str(grant.admin_profile.id))
            grant.team_members.set(team_members)
            if 'edit-description' in request.POST:
                grant.description = request.POST.get('edit-description')
                grant.description_rich = request.POST.get(
                    'edit-description_rich')
            grant.save()
            record_grant_activity_helper('update_grant', grant, profile)
            return redirect(
                reverse('grants:details', args=(grant.pk, grant.slug)))

    tab = request.GET.get('tab', 'description')
    params = {
        'active': 'grant_details',
        'clr_matching_banners_style': clr_matching_banners_style,
        'grant': grant,
        'tab': tab,
        'title': matching_live + grant.title,
        'card_desc': grant.description,
        'avatar_url': grant.logo.url if grant.logo else None,
        'subscriptions': subscriptions,
        'cancelled_subscriptions': cancelled_subscriptions,
        'contributions': contributions,
        'user_subscription': user_subscription,
        'user_non_errored_subscription': user_non_errored_subscription,
        'is_admin': is_admin,
        'grant_is_inactive': not grant.active,
        'updates': updates,
        'milestones': milestones,
        'keywords': get_keywords(),
        'activity_count': activity_count,
        'contributors': contributors,
        'clr_active': clr_active,
        'is_team_member': is_team_member,
    }

    if tab == 'stats':
        params['max_graph'] = grant.history_by_month_max
        params['history'] = json.dumps(grant.history_by_month)

    if add_cancel_params:
        add_in_params = {
            'recommend_gas_price':
            recommend_min_gas_price_to_confirm_in_time(4),
            'recommend_gas_price_slow':
            recommend_min_gas_price_to_confirm_in_time(120),
            'recommend_gas_price_avg':
            recommend_min_gas_price_to_confirm_in_time(15),
            'recommend_gas_price_fast':
            recommend_min_gas_price_to_confirm_in_time(1),
            'eth_usd_conv_rate':
            eth_usd_conv_rate(),
            'conf_time_spread':
            conf_time_spread(),
            'gas_advisories':
            gas_advisories(),
        }
        for key, value in add_in_params.items():
            params[key] = value

    return TemplateResponse(request, 'grants/detail/index.html', params)
Example #8
0
def grant_fund(request, grant_id, grant_slug):
    """Handle grant funding."""
    try:
        grant = Grant.objects.get(pk=grant_id, slug=grant_slug)
    except Grant.DoesNotExist:
        raise Http404

    profile = get_profile(request)

    if not grant.active:
        params = {
            'active': 'grant_error',
            'title': _('Grant Ended'),
            'grant': grant,
            'text': _('This Grant is not longer active.')
        }
        return TemplateResponse(request, 'grants/shared/error.html', params)

    if grant.admin_profile == profile:
        params = {
            'active': 'grant_error',
            'title': _('Invalid Grant Subscription'),
            'grant': grant,
            'text': _('You cannot fund your own Grant.')
        }
        return TemplateResponse(request, 'grants/shared/error.html', params)

    active_subscription = Subscription.objects.select_related('grant').filter(
        grant=grant_id, active=True, contributor_profile=request.user.profile)

    if active_subscription:
        params = {
            'active': 'grant_error',
            'title': _('Subscription Exists'),
            'grant': grant,
            'text':
            _('You already have an active subscription for this grant.')
        }
        return TemplateResponse(request, 'grants/shared/error.html', params)

    if request.method == 'POST':
        if 'contributor_address' in request.POST:
            subscription = Subscription()

            subscription.active = False
            subscription.contributor_address = request.POST.get(
                'contributor_address', '')
            subscription.amount_per_period = request.POST.get(
                'amount_per_period', 0)
            subscription.real_period_seconds = request.POST.get(
                'real_period_seconds', 2592000)
            subscription.frequency = request.POST.get('frequency', 30)
            subscription.frequency_unit = request.POST.get(
                'frequency_unit', 'days')
            subscription.token_address = request.POST.get('token_address', '')
            subscription.token_symbol = request.POST.get('token_symbol', '')
            subscription.gas_price = request.POST.get('gas_price', 0)
            subscription.new_approve_tx_id = request.POST.get(
                'sub_new_approve_tx_id', '')
            subscription.num_tx_approved = request.POST.get(
                'num_tx_approved', 1)
            subscription.network = request.POST.get('network', '')
            subscription.contributor_profile = profile
            subscription.grant = grant
            subscription.save()
            return JsonResponse({
                'success': True,
            })

        if 'signature' in request.POST:
            sub_new_approve_tx_id = request.POST.get('sub_new_approve_tx_id',
                                                     '')
            subscription = Subscription.objects.filter(
                new_approve_tx_id=sub_new_approve_tx_id).first()
            subscription.active = True
            subscription.subscription_hash = request.POST.get(
                'subscription_hash', '')
            subscription.contributor_signature = request.POST.get(
                'signature', '')
            subscription.save()

            value_usdt = subscription.get_converted_amount()
            if value_usdt:
                grant.monthly_amount_subscribed += subscription.get_converted_monthly_amount(
                )

            grant.save()
            new_supporter(grant, subscription)
            thank_you_for_supporting(grant, subscription)
            return JsonResponse({
                'success':
                True,
                'url':
                reverse('grants:details', args=(grant.pk, grant.slug))
            })

    params = {
        'active':
        'fund_grant',
        'title':
        _('Fund Grant'),
        'card_desc':
        _('Provide sustainable funding for Open Source with Gitcoin Grants'),
        'subscription': {},
        'grant_has_no_token':
        True if grant.token_address
        == '0x0000000000000000000000000000000000000000' else False,
        'grant':
        grant,
        'keywords':
        get_keywords(),
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(4),
        'recommend_gas_price_slow':
        recommend_min_gas_price_to_confirm_in_time(120),
        'recommend_gas_price_avg':
        recommend_min_gas_price_to_confirm_in_time(15),
        'recommend_gas_price_fast':
        recommend_min_gas_price_to_confirm_in_time(1),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
        'gas_advisories':
        gas_advisories(),
    }
    return TemplateResponse(request, 'grants/fund.html', params)
Example #9
0
def grant_new(request):
    """Handle new grant."""
    profile = get_profile(request)

    if request.method == 'POST':
        if 'title' in request.POST:
            logo = request.FILES.get('input_image', None)
            receipt = json.loads(request.POST.get('receipt', '{}'))
            team_members = request.POST.getlist('team_members[]')

            grant_kwargs = {
                'title':
                request.POST.get('title', ''),
                'description':
                request.POST.get('description', ''),
                'description_rich':
                request.POST.get('description_rich', ''),
                'reference_url':
                request.POST.get('reference_url', ''),
                'admin_address':
                request.POST.get('admin_address', ''),
                'contract_owner_address':
                request.POST.get('contract_owner_address', ''),
                'token_address':
                request.POST.get('token_address', ''),
                'token_symbol':
                request.POST.get('token_symbol', ''),
                'amount_goal':
                request.POST.get('amount_goal', 1),
                'contract_version':
                request.POST.get('contract_version', ''),
                'deploy_tx_id':
                request.POST.get('transaction_hash', ''),
                'network':
                request.POST.get('network', 'mainnet'),
                'metadata':
                receipt,
                'admin_profile':
                profile,
                'logo':
                logo,
                'hidden':
                True,
            }
            grant = Grant.objects.create(**grant_kwargs)
            new_grant_admin(grant)
            team_members.append(profile.id)
            grant.team_members.add(*list(
                filter(lambda member_id: member_id > 0, map(int,
                                                            team_members))))
            return JsonResponse({
                'success': True,
            })

        if 'contract_address' in request.POST:
            tx_hash = request.POST.get('transaction_hash', '')
            if not tx_hash:
                return JsonResponse({
                    'success': False,
                    'info': 'no tx hash',
                    'url': None,
                })

            grant = Grant.objects.filter(deploy_tx_id=tx_hash).first()
            grant.contract_address = request.POST.get('contract_address', '')
            print(tx_hash, grant.contract_address)
            messages.info(
                request,
                _('Thank you for posting this Grant.  Share the Grant URL with your friends/followers to raise your first tokens.'
                  ))
            grant.save()
            record_grant_activity_helper('new_grant', grant, profile)
            new_grant(grant, profile)
            return JsonResponse({
                'success':
                True,
                'url':
                reverse('grants:details', args=(grant.pk, grant.slug))
            })

    params = {
        'active':
        'new_grant',
        'title':
        _('New Grant'),
        'card_desc':
        _('Provide sustainable funding for Open Source with Gitcoin Grants'),
        'profile':
        profile,
        'grant': {},
        'keywords':
        get_keywords(),
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(4),
        'recommend_gas_price_slow':
        recommend_min_gas_price_to_confirm_in_time(120),
        'recommend_gas_price_avg':
        recommend_min_gas_price_to_confirm_in_time(15),
        'recommend_gas_price_fast':
        recommend_min_gas_price_to_confirm_in_time(1),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
        'gas_advisories':
        gas_advisories(),
        'trusted_relayer':
        settings.GRANTS_OWNER_ACCOUNT
    }
    return TemplateResponse(request, 'grants/new.html', params)
Example #10
0
def grant_fund(request, grant_id, grant_slug):
    """Handle grant funding."""
    try:
        grant = Grant.objects.get(pk=grant_id, slug=grant_slug)
    except Grant.DoesNotExist:
        raise Http404

    profile = get_profile(request)

    if not grant.active:
        params = {
            'active': 'grant_error',
            'title': _('Grant Ended'),
            'grant': grant,
            'text': _('This Grant is not longer active.')
        }
        return TemplateResponse(request, 'grants/shared/error.html', params)

    if grant.admin_profile == profile:
        params = {
            'active': 'grant_error',
            'title': _('Invalid Grant Subscription'),
            'grant': grant,
            'text': _('You cannot fund your own Grant.')
        }
        return TemplateResponse(request, 'grants/shared/error.html', params)

    active_subscription = Subscription.objects.select_related('grant').filter(
        grant=grant_id,
        active=True,
        error=False,
        contributor_profile=request.user.profile)

    if active_subscription:
        params = {
            'active': 'grant_error',
            'title': _('Subscription Exists'),
            'grant': grant,
            'text':
            _('You already have an active subscription for this grant.')
        }
        return TemplateResponse(request, 'grants/shared/error.html', params)

    if grant.contract_address == '0x0':
        messages.info(
            request,
            _('This grant is not configured to accept funding at this time.  Please contact [email protected] if you believe this message is in error!'
              ))
        logger.error(
            f"Grant {grant.pk} is not properly configured for funding.  Please set grant.contract_address on this grant"
        )
        return redirect(reverse('grants:details', args=(grant.pk, grant.slug)))

    if request.method == 'POST':
        if 'contributor_address' in request.POST:
            subscription = Subscription()

            subscription.active = False
            subscription.contributor_address = request.POST.get(
                'contributor_address', '')
            subscription.amount_per_period = request.POST.get(
                'amount_per_period', 0)
            subscription.real_period_seconds = request.POST.get(
                'real_period_seconds', 2592000)
            subscription.frequency = request.POST.get('frequency', 30)
            subscription.frequency_unit = request.POST.get(
                'frequency_unit', 'days')
            subscription.token_address = request.POST.get('token_address', '')
            subscription.token_symbol = request.POST.get('token_symbol', '')
            subscription.gas_price = request.POST.get('gas_price', 0)
            subscription.new_approve_tx_id = request.POST.get(
                'sub_new_approve_tx_id', '0x0')
            subscription.num_tx_approved = request.POST.get(
                'num_tx_approved', 1)
            subscription.network = request.POST.get('network', '')
            subscription.contributor_profile = profile
            subscription.grant = grant
            subscription.save()

            # one time payments
            if int(subscription.num_tx_approved) == 1:
                subscription.successful_contribution(
                    subscription.new_approve_tx_id)
                subscription.error = True  #cancel subs so it doesnt try to bill again
                subscription.subminer_comments = "skipping subminer bc this is a 1 and done subscription, and tokens were alredy sent"
                subscription.save()
                record_subscription_activity_helper('new_grant_contribution',
                                                    subscription, profile)
            else:
                record_subscription_activity_helper('new_grant_subscription',
                                                    subscription, profile)

            messages.info(
                request,
                _('Your subscription has been created. It will bill within the next 5 minutes or so. Thank you for supporting Open Source !'
                  ))

            return JsonResponse({
                'success': True,
            })

        if 'signature' in request.POST:
            sub_new_approve_tx_id = request.POST.get('sub_new_approve_tx_id',
                                                     '')
            subscription = Subscription.objects.filter(
                new_approve_tx_id=sub_new_approve_tx_id).first()
            subscription.active = True
            subscription.subscription_hash = request.POST.get(
                'subscription_hash', '')
            subscription.contributor_signature = request.POST.get(
                'signature', '')
            subscription.save()

            value_usdt = subscription.get_converted_amount()
            if value_usdt:
                grant.monthly_amount_subscribed += subscription.get_converted_monthly_amount(
                )

            grant.save()
            new_supporter(grant, subscription)
            thank_you_for_supporting(grant, subscription)
            return JsonResponse({
                'success':
                True,
                'url':
                reverse('grants:details', args=(grant.pk, grant.slug))
            })

    splitter_contract_address = settings.SPLITTER_CONTRACT_ADDRESS

    params = {
        'active':
        'fund_grant',
        'title':
        _('Fund Grant'),
        'card_desc':
        _('Provide sustainable funding for Open Source with Gitcoin Grants'),
        'subscription': {},
        'grant_has_no_token':
        True if grant.token_address
        == '0x0000000000000000000000000000000000000000' else False,
        'grant':
        grant,
        'keywords':
        get_keywords(),
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(4),
        'recommend_gas_price_slow':
        recommend_min_gas_price_to_confirm_in_time(120),
        'recommend_gas_price_avg':
        recommend_min_gas_price_to_confirm_in_time(15),
        'recommend_gas_price_fast':
        recommend_min_gas_price_to_confirm_in_time(1),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
        'gas_advisories':
        gas_advisories(),
        'splitter_contract_address':
        settings.SPLITTER_CONTRACT_ADDRESS,
        'gitcoin_donation_address':
        settings.GITCOIN_DONATION_ADDRESS
    }
    return TemplateResponse(request, 'grants/fund.html', params)
Example #11
0
def gas(request):
    context = {
        'conf_time_spread': conf_time_spread(),
        'title': 'Live Gas Usage => Predicted Conf Times'
        }
    return TemplateResponse(request, 'gas.html', context)