Exemple #1
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)
Exemple #2
0
def milestones(request, grant_id, grant_slug):
    profile = get_profile(request)
    grant = Grant.objects.prefetch_related('milestones').get(pk=grant_id,
                                                             slug=grant_slug)
    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 not is_team_member:
        return redirect(reverse('grants:details', args=(grant.pk, grant.slug)))

    if request.method == "POST":
        method = request.POST.get('method')

        if method == "POST":
            form = MilestoneForm(request.POST)
            milestone = form.save(commit=False)
            milestone.grant = grant
            milestone.save()

        if method == "PUT":
            milestone_id = request.POST.get('milestone_id')
            milestone = Milestone.objects.get(pk=milestone_id)
            milestone.completion_date = request.POST.get('completion_date')
            milestone.save()

        if method == "DELETE":
            milestone_id = request.POST.get('milestone_id')
            milestone = grant.milestones.get(pk=milestone_id)
            milestone.delete()

        return redirect(
            reverse('grants:milestones', args=(grant.pk, grant.slug)))

    form = MilestoneForm()
    milestones = grant.milestones.order_by('due_date')

    params = {
        'active':
        'grant_milestones',
        'title':
        _('Grant Milestones'),
        'card_desc':
        _('Provide sustainable funding for Open Source with Gitcoin Grants'),
        'grant':
        grant,
        'milestones':
        milestones,
        'form':
        form,
        'keywords':
        get_keywords(),
    }
    return TemplateResponse(request, 'grants/milestones.html', params)
Exemple #3
0
def new_matching_partner(request):

    tx_hash = request.POST.get('hash')
    tx_amount = request.POST.get('amount')
    profile = get_profile(request)

    def get_json_response(message, status):
        return JsonResponse({
            'status': status,
            'message': message
        },
                            status=status)

    def is_verified(tx_details, tx_hash, tx_amount, network):
        gitcoin_account = '0x00De4B13153673BCAE2616b67bf822500d325Fc3'
        return has_tx_mined(tx_hash, network) and\
            tx_details.to.lower() == gitcoin_account.lower()

    if not request.user.is_authenticated:
        return get_json_response("Not Authorized", 403)

    if not profile:
        return get_json_response("Profile not found.", 404)

    if request.POST and tx_hash:
        network = 'mainnet'
        web3 = get_web3(network)
        tx = web3.eth.getTransaction(tx_hash)
        if not tx:
            raise Http404
        match_pledge = MatchPledge.objects.create(profile=profile,
                                                  amount=convert_amount(
                                                      tx.value / 10**18, 'ETH',
                                                      'USDT'),
                                                  data=json.dumps({
                                                      'tx_hash':
                                                      tx_hash,
                                                      'network':
                                                      network,
                                                      'from':
                                                      tx['from'],
                                                      'to':
                                                      tx.to,
                                                      'tx_amount':
                                                      tx.value
                                                  }))
        match_pledge.active = is_verified(tx, tx_hash, tx_amount, network)
        match_pledge.save()

        return get_json_response(
            """Thank you for volunteering to match on Gitcoin Grants.
            You are supporting open source, and we thank you.""", 201)

    return get_json_response("Wrong request.", 400)
Exemple #4
0
def profile(request):
    """Show grants profile of logged in user."""
    limit = request.GET.get('limit', 25)
    page = request.GET.get('page', 1)
    sort = request.GET.get('sort', '-created_on')

    profile = get_profile(request)
    _grants_pks = Grant.objects.filter(Q(admin_profile=profile) | Q(team_members__in=[profile])).values_list(
        'pk', flat=True
    )
    _grants = Grant.objects.prefetch_related('team_members') \
        .filter(pk__in=_grants_pks).order_by(sort)
    sub_grants = Grant.objects.filter(subscriptions__contributor_profile=profile).order_by(sort)

    sub_contributions = []
    contributions = []

    for contribution in Contribution.objects.filter(subscription__contributor_profile=profile).order_by('-pk'):
        instance = {
            "cont": contribution,
            "sub": contribution.subscription,
            "grant":  contribution.subscription.grant,
            "profile": contribution.subscription.contributor_profile
        }
        sub_contributions.append(instance)

    for _grant in _grants:
        subs = Subscription.objects.filter(grant=_grant)
        for _sub in subs:
            conts = Contribution.objects.filter(subscription=_sub)
            for _cont in conts:
                instance = {
                    "cont": _cont,
                    "sub": _sub,
                    "grant":  _grant,
                    "profile": _sub.contributor_profile
                }
                contributions.append(instance)

    paginator = Paginator(_grants, limit)
    grants = paginator.get_page(page)

    params = {
        'active': 'profile',
        'title': _('My Grants'),
        'card_desc': _('Provide sustainable funding for Open Source with Gitcoin Grants'),
        'grants': grants,
        'history': contributions,
        'sub_grants': sub_grants,
        'sub_history': sub_contributions
    }

    return TemplateResponse(request, 'grants/profile/index.html', params)
Exemple #5
0
def grant_new_whitelabel(request):
    """Create a new grant, with a branded creation form for specific tribe"""

    profile = get_profile(request)

    params = {
        'active':
        'new_grant',
        'title':
        _('Matic Build-n-Earn x Gitcoin'),
        'card_desc':
        _('Earn Rewards by Making Your DApps Superior'),
        'card_player_thumb_override':
        request.build_absolute_uri(
            static('v2/images/grants/maticxgitcoin.png')),
        'profile':
        profile,
        'is_logged_in':
        1 if profile else 0,
        '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-whitelabel.html', params)
Exemple #6
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)
Exemple #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'))
        voucher_fundings = [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 = is_grant_team_member(grant, profile)

    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)))

    # handle grant updates unsubscribe
    key = 'unsubscribed_profiles'
    is_unsubscribed_from_updates_from_this_grant = request.user.is_authenticated and request.user.profile.pk in grant.metadata.get(key, [])
    if request.GET.get('unsubscribe') and request.user.is_authenticated:
        ups = grant.metadata.get(key, [])
        ups.append(request.user.profile.pk)
        grant.metadata[key] = ups
        grant.save()
        messages.info(
                request,
                _('You have been unsubscribed from the updates from this grant.')
            )
        is_unsubscribed_from_updates_from_this_grant = True

    tab = request.GET.get('tab', 'activity')
    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(),
        'target': f'/activity?what=grant:{grant.pk}',
        'activity_count': activity_count,
        'contributors': contributors,
        'clr_active': clr_active,
        'show_clr_card': show_clr_card,
        'is_team_member': is_team_member,
        'voucher_fundings': voucher_fundings,
        'is_unsubscribed_from_updates_from_this_grant': is_unsubscribed_from_updates_from_this_grant,
        'tags': [(f'Email Grant Funders ({len(contributors)})', 'bullhorn')] if is_team_member else [],
    }

    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)
Exemple #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':
        subscription = Subscription()

        subscription.subscription_hash = request.POST.get(
            'subscription_hash', '')
        subscription.contributor_signature = request.POST.get('signature', '')
        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('denomination', '')
        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.network = request.POST.get('network', '')
        subscription.contributor_profile = profile
        subscription.grant = grant
        subscription.save()
        new_supporter(grant, subscription)
        thank_you_for_supporting(grant, subscription)
        return redirect(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)
Exemple #9
0
def grant_new(request):
    """Handle new grant."""
    if not request.user.has_perm('grants.add_grant'):
        messages.info(
            request,
            _('Grants is still in beta. To create a Grant ping us at [email protected]'
              ))
        return redirect(reverse('grants:grants'))

    profile = get_profile(request)

    if request.method == '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('input_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('denomination', ''),
            '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', ''),
            'contract_address':
            request.POST.get('contract_address', ''),
            'network':
            request.POST.get('network', 'mainnet'),
            'metadata':
            receipt,
            'admin_profile':
            profile,
            'logo':
            logo,
        }
        grant = Grant.objects.create(**grant_kwargs)
        new_grant(grant, profile)

        team_members.append(profile.id)
        grant.team_members.add(*list(
            filter(lambda member_id: member_id > 0, map(int, team_members))))
        return redirect(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)
Exemple #10
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)
        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 '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.admin_profile = admin_profile
            grant.description = request.POST.get('edit-description')
            team_members = request.POST.getlist('edit-grant_members[]')
            team_members.append(str(admin_profile.id))
            grant.team_members.set(team_members)
            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,
        '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(),
    }
    return TemplateResponse(request, 'grants/detail.html', params)
Exemple #11
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)
        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()
        add_cancel_params = user_subscription
    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)))
    is_admin = (grant.admin_profile.id
                == profile.id) if profile and grant.admin_profile else False
    if is_admin:
        add_cancel_params = True

    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': is_admin,
        'grant_is_inactive': not grant.active,
        'updates': updates,
        'milestones': milestones,
        'keywords': get_keywords(),
    }

    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

    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)
Exemple #12
0
def grant_details(request, grant_id, grant_slug):
    """Display the Grant details page."""
    tab = request.GET.get('tab', 'description')
    profile = get_profile(request)
    add_cancel_params = False
    try:
        grant = None
        try:
            grant = Grant.objects.prefetch_related(
                'subscriptions', 'team_members').get(pk=grant_id,
                                                     slug=grant_slug)
        except Grant.DoesNotExist:
            grant = Grant.objects.prefetch_related(
                'subscriptions', 'team_members').get(pk=grant_id)

        increment_view_count.delay([grant.pk], grant.content_type,
                                   request.user.id, 'individual')
        subscriptions = grant.subscriptions.filter(
            active=True, error=False,
            is_postive_vote=True).order_by('-created_on')
        cancelled_subscriptions = grant.subscriptions.filter(
            active=False, error=False,
            is_postive_vote=True).order_by('-created_on')

        activity_count = grant.contribution_count
        contributors = []
        contributions = []
        negative_contributions = []
        voucher_fundings = []
        if tab in ['transactions', 'contributors']:
            _contributions = Contribution.objects.filter(
                subscription__in=grant.subscriptions.all().cache(
                    timeout=60)).cache(timeout=60)
            negative_contributions = _contributions.filter(
                subscription__is_postive_vote=False)
            _contributions = _contributions.filter(
                subscription__is_postive_vote=True)
            phantom_funds = grant.phantom_funding.all().cache(timeout=60)
            contributions = list(_contributions.order_by('-created_on'))
            voucher_fundings = [
                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 = is_grant_team_member(grant, profile)

    if request.method == 'POST' and (is_team_member or request.user.is_staff):
        grant.last_update = timezone.now()
        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 'edit-title' in request.POST:
            grant.title = request.POST.get('edit-title')
            grant.reference_url = request.POST.get('edit-reference_url')
            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()

            form_category_ids = request.POST.getlist('edit-categories[]')
            '''Overwrite the existing categories and then add the new ones'''
            grant.categories.clear()
            add_form_categories_to_grant(form_category_ids, grant,
                                         grant.grant_type)

            record_grant_activity_helper('update_grant', grant, profile)
            return redirect(
                reverse('grants:details', args=(grant.pk, grant.slug)))

    # handle grant updates unsubscribe
    key = 'unsubscribed_profiles'
    is_unsubscribed_from_updates_from_this_grant = request.user.is_authenticated and request.user.profile.pk in grant.metadata.get(
        key, [])
    if request.GET.get('unsubscribe') and request.user.is_authenticated:
        ups = grant.metadata.get(key, [])
        ups.append(request.user.profile.pk)
        grant.metadata[key] = ups
        grant.save()
        messages.info(
            request,
            _('You have been unsubscribed from the updates from this grant.'))
        is_unsubscribed_from_updates_from_this_grant = True

    try:
        what = f'grant:{grant.pk}'
        pinned = PinnedPost.objects.get(what=what)
    except PinnedPost.DoesNotExist:
        pinned = None
    params = {
        'active':
        'grant_details',
        'clr_matching_banners_style':
        clr_matching_banners_style,
        'grant':
        grant,
        'tab':
        tab,
        'title':
        matching_live_tiny + grant.title + " | Grants",
        'card_desc':
        grant.description,
        'avatar_url':
        grant.logo.url if grant.logo else None,
        'subscriptions':
        subscriptions,
        'cancelled_subscriptions':
        cancelled_subscriptions,
        'contributions':
        contributions,
        'negative_contributions':
        negative_contributions,
        'user_subscription':
        user_subscription,
        'user_non_errored_subscription':
        user_non_errored_subscription,
        'is_admin':
        is_admin,
        'grant_is_inactive':
        not grant.active,
        'keywords':
        get_keywords(),
        'target':
        f'/activity?what={what}',
        'pinned':
        pinned,
        'what':
        what,
        'activity_count':
        activity_count,
        'contributors':
        contributors,
        'clr_active':
        clr_active,
        'is_team_member':
        is_team_member,
        'voucher_fundings':
        voucher_fundings,
        'is_unsubscribed_from_updates_from_this_grant':
        is_unsubscribed_from_updates_from_this_grant,
        'is_round_5_5':
        False,
        'options':
        [(f'Email Grant Funders ({grant.contributor_count})', 'bullhorn',
          'Select this option to email your status update to all your funders.'
          )] if is_team_member else [],
    }

    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)
Exemple #13
0
def grant_new(request):
    """Handle new grant."""
    if not request.user.has_perm('grants.add_grant'):
        return redirect('https://gitcoin.typeform.com/to/C2IocD')

    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', '')
            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(),
    }

    return TemplateResponse(request, 'grants/new.html', params)
Exemple #14
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)
Exemple #15
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': _('Fund - Grant Ended'),
            'grant': grant,
            'text': _('This Grant has ended.'),
            'subtext': _('Contributions can no longer be made this grant')
        }
        return TemplateResponse(request, 'grants/shared/error.html', params)

    if is_grant_team_member(grant, profile):
        params = {
            'active':
            'grant_error',
            'title':
            _('Fund - Grant funding blocked'),
            'grant':
            grant,
            'text':
            _('This Grant cannot be funded'),
            'subtext':
            _('Grant team members cannot contribute to their own grant.')
        }
        return TemplateResponse(request, 'grants/shared/error.html', params)

    if grant.link_to_new_grant:
        params = {
            'active': 'grant_error',
            'title': _('Fund - Grant Migrated'),
            'grant': grant.link_to_new_grant,
            'text': f'This Grant has ended',
            'subtext':
            'Contributions can no longer be made to this grant. <br> Visit the new grant to contribute.',
            'button_txt': 'View New 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,
        is_postive_vote=True)

    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 not grant.configured_to_receieve_funding:
        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':
        from grants.tasks import process_grant_contribution
        process_grant_contribution.delay(grant_id, grant_slug, profile.pk,
                                         request.POST)

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

    raise Http404
Exemple #16
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_type = request.POST.get('grant_type', 'tech')

            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', ''),
                'contract_version':
                request.POST.get('contract_version', ''),
                'deploy_tx_id':
                request.POST.get('transaction_hash', ''),
                'network':
                request.POST.get('network', 'mainnet'),
                'twitter_handle_1':
                request.POST.get('handle1', ''),
                'twitter_handle_2':
                request.POST.get('handle2', ''),
                'metadata':
                receipt,
                'last_update':
                timezone.now(),
                'admin_profile':
                profile,
                'logo':
                logo,
                'hidden':
                False,
                'clr_prediction_curve': [[0.0, 0.0, 0.0] for x in range(0, 6)],
                'grant_type':
                grant_type
            }
            grant = Grant.objects.create(**grant_kwargs)
            new_grant_admin(grant)

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

            team_members = [int(i) for i in team_members if i != '']

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

            form_category_ids = request.POST.getlist('categories[]')
            form_category_ids = (form_category_ids[0].split(','))
            form_category_ids = list(set(form_category_ids))

            add_form_categories_to_grant(form_category_ids, grant, grant_type)

            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': grant.url,
            })

    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)
Exemple #17
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': _('Fund - Grant Ended'),
            'grant': grant,
            'text': _('This Grant has ended.'),
            'subtext': _('Contributions can no longer be made this grant')
        }
        return TemplateResponse(request, 'grants/shared/error.html', params)

    if is_grant_team_member(grant, profile):
        params = {
            'active': 'grant_error',
            'title': _('Fund - Grant funding blocked'),
            'grant': grant,
            'text': _('This Grant cannot be funded'),
            'subtext': _('Grant team members cannot contribute to their own grant.')
        }
        return TemplateResponse(request, 'grants/shared/error.html', params)

    if grant.link_to_new_grant:
        params = {
            'active': 'grant_error',
            'title': _('Fund - Grant Migrated'),
            'grant': grant.link_to_new_grant,
            'text': f'This Grant has ended',
            'subtext': 'Contributions can no longer be made to this grant. <br> Visit the new grant to contribute.',
            'button_txt': 'View New 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.comments = request.POST.get('comment', '')
            subscription.save()

            # one time payments
            activity = None
            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()
                activity = record_subscription_activity_helper('new_grant_contribution', subscription, profile)
            else:
                activity = record_subscription_activity_helper('new_grant_subscription', subscription, profile)

            if 'comment' in request.POST:
                comment = request.POST.get('comment')
                if comment and activity:
                    comment = Comment.objects.create(
                        profile=request.user.profile,
                        activity=activity,
                        comment=comment)

            # 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() and clr_active
    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)
            record_grant_activity_helper('new_grant_contribution', grant, request.user.profile)

        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,
        'clr_active': clr_active,
        'total_clr_pot': total_clr_pot,
    }
    return TemplateResponse(request, 'grants/fund.html', params)
Exemple #18
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.filter(round_number=3)
        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)))

    params = {
        'active': 'grant_details',
        'clr_matching_banners_style': clr_matching_banners_style,
        'grant': grant,
        'tab': request.GET.get('tab', 'description'),
        '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 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)
Exemple #19
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': _('Fund - Grant Ended'),
            'grant': grant,
            'text': _('This Grant has ended.'),
            'subtext': _('Contributions can no longer be made this grant')
        }
        return TemplateResponse(request, 'grants/shared/error.html', params)

    if is_grant_team_member(grant, profile):
        params = {
            'active': 'grant_error',
            'title': _('Fund - Grant funding blocked'),
            'grant': grant,
            'text': _('This Grant cannot be funded'),
            'subtext': _('Grant team members cannot contribute to their own grant.')
        }
        return TemplateResponse(request, 'grants/shared/error.html', params)

    if grant.link_to_new_grant:
        params = {
            'active': 'grant_error',
            'title': _('Fund - Grant Migrated'),
            'grant': grant.link_to_new_grant,
            'text': f'This Grant has ended',
            'subtext': 'Contributions can no longer be made to this grant. <br> Visit the new grant to contribute.',
            'button_txt': 'View New 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, is_postive_vote=True
    )

    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()

            if grant.negative_voting_enabled:
                #is_postive_vote = True if request.POST.get('is_postive_vote', 1) else False
                is_postive_vote = request.POST.get('match_direction', '+') == '+'
            else:
                is_postive_vote = True
            subscription.is_postive_vote = is_postive_vote

            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.comments = request.POST.get('comment', '')
            subscription.save()

            # one time payments
            activity = None
            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()
                activity = record_subscription_activity_helper('new_grant_contribution', subscription, profile)
            else:
                activity = record_subscription_activity_helper('new_grant_subscription', subscription, profile)

            if 'comment' in request.POST:
                comment = request.POST.get('comment')
                if comment and activity:
                    profile = request.user.profile
                    if subscription and subscription.negative:
                        profile = Profile.objects.filter(handle='gitcoinbot').first()
                        comment = f"Comment from contributor: {comment}"
                    comment = Comment.objects.create(
                        profile=profile,
                        activity=activity,
                        comment=comment)

            message = 'Your contribution has succeeded. Thank you for supporting Public Goods on Gitcoin !'
            if request.session.get('send_notification'):
                msg_html = request.session.get('msg_html')
                cta_text = request.session.get('cta_text')
                cta_url = request.session.get('cta_url')
                to_user = request.user
                send_notification_to_user_from_gitcoinbot(to_user, cta_url, cta_text, msg_html)
            if int(subscription.num_tx_approved) > 1:
                message = 'Your subscription has been created. It will bill within the next 5 minutes or so. Thank you for supporting Public Goods on Gitcoin !'

            messages.info(
                request,
                message
            )

            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()
            if not subscription.negative:
                new_supporter(grant, subscription)
                thank_you_for_supporting(grant, subscription)
            return JsonResponse({
                'success': True,
                'url': reverse('grants:details', args=(grant.pk, grant.slug))
            })

    # handle phantom funding
    active_tab = 'normal'
    fund_reward = None
    round_number = clr_round
    can_phantom_fund = request.user.is_authenticated and request.user.groups.filter(name='phantom_funders_round_5').exists() and clr_active
    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
    fund_reward = get_fund_reward(request, grant)
    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
            pt = PhantomFunding.objects.create(grant=grant, profile=request.user.profile, round_number=round_number)
            record_grant_activity_helper('new_grant_contribution', grant, request.user.profile, amount=pt.value, token='DAI')

        messages.info(
            request,
            msg
        )
        is_phantom_funding_this_grant = not is_phantom_funding_this_grant
    images = [
        'new.svg',
        'torchbearer.svg',
        'robots.png',
        'profile/fund.svg',
    ]
    img = random.choice(images)
    params = {
        'profile': profile,
        'active': 'fund_grant',
        'title': matching_live + grant.title + " | Fund Now",
        'card_desc': grant.description,
        'avatar_url': grant.logo.url if grant.logo else None,
        'subscription': {},
        'show_tweet_modal': show_tweet_modal,
        'direction': request.GET.get('direction', '+'),
        'grant_has_no_token': True if grant.token_address == '0x0000000000000000000000000000000000000000' else False,
        'grant': grant,
        'img': img,
        '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,
        'clr_active': clr_active,
        'total_clr_pot': total_clr_pot,
    }
    return TemplateResponse(request, 'grants/fund.html', params)
Exemple #20
0
def grants_by_grant_type(request, grant_type):
    """Handle grants explorer."""

    # hack for vivek
    if grant_type == 'change':
        new_url = request.get_full_path().replace('/change',
                                                  '/crypto-for-black-lives')
        return redirect(new_url)
    if grant_type == 'crypto-for-black-lives':
        grant_type = 'change'

    limit = request.GET.get('limit', 6)
    page = request.GET.get('page', 1)
    sort = request.GET.get('sort_option', 'weighted_shuffle')
    network = request.GET.get('network', 'mainnet')
    keyword = request.GET.get('keyword', '')
    state = request.GET.get('state', 'active')
    category = request.GET.get('category', '')
    profile = get_profile(request)
    _grants = None
    bg = 4
    bg = f"{bg}.jpg"
    mid_back = 'bg14.png'
    bottom_back = 'bg13.gif'
    if grant_type == 'tech':
        bottom_back = '0.png'
        bg = '0.jpg'
    if grant_type == 'tech':
        bottom_back = 'bg20-2.png'
        bg = '1.jpg'
    if grant_type == 'media':
        bottom_back = 'bg16.gif'
        bg = '2.jpg'
    if grant_type == 'health':
        bottom_back = 'health.jpg'
        bg = 'health2.jpg'
    if grant_type in ['about', 'activity']:
        bg = '3.jpg'
    show_past_clr = False

    sort_by_index = None
    sort_by_clr_pledge_matching_amount = None
    if 'match_pledge_amount_' in sort:
        sort_by_clr_pledge_matching_amount = int(sort.split('amount_')[1])

    _grants = Grant.objects.filter(network=network,
                                   hidden=False).keyword(keyword)
    try:
        _grants = _grants.order_by(sort, 'pk')
        ____ = _grants.first()
    except Exception as e:
        print(e)
        return redirect('/grants')
    if state == 'active':
        _grants = _grants.active()
    if keyword:
        grant_type = ''
    else:
        # dotn do search by cateogry
        if grant_type != 'all':
            _grants = _grants.filter(grant_type=grant_type)

    clr_prediction_curve_schema_map = {10**x: x + 1 for x in range(0, 5)}
    if sort_by_clr_pledge_matching_amount in clr_prediction_curve_schema_map.keys(
    ):
        sort_by_index = clr_prediction_curve_schema_map.get(
            sort_by_clr_pledge_matching_amount, 0)
        field_name = f'clr_prediction_curve__{sort_by_index}__2'
        _grants = _grants.order_by(f"-{field_name}")

    if category:
        _grants = _grants.filter(Q(categories__category__icontains=category))

    _grants = _grants.prefetch_related('categories')
    paginator = Paginator(_grants, limit)
    grants = paginator.get_page(page)
    partners = MatchPledge.objects.filter(
        active=True,
        pledge_type=grant_type) if grant_type else MatchPledge.objects.filter(
            active=True)

    now = datetime.datetime.now()

    # record view
    pks = list([grant.pk for grant in grants])
    if len(pks):
        increment_view_count.delay(pks, grants[0].content_type,
                                   request.user.id, 'index')

    current_partners = partners.filter(end_date__gte=now).order_by('-amount')
    past_partners = partners.filter(end_date__lt=now).order_by('-amount')
    current_partners_fund = 0

    for partner in current_partners:
        current_partners_fund += partner.amount

    grant_amount = 0
    grant_stats = Stat.objects.filter(key='grants', ).order_by('-pk')
    if grant_stats.exists():
        grant_amount = lazy_round_number(grant_stats.first().val)

    tech_grants_count = Grant.objects.filter(network=network,
                                             hidden=False,
                                             grant_type='tech').count()
    media_grants_count = Grant.objects.filter(network=network,
                                              hidden=False,
                                              grant_type='media').count()
    health_grants_count = Grant.objects.filter(network=network,
                                               hidden=False,
                                               grant_type='health').count()
    matic_grants_count = Grant.objects.filter(network=network,
                                              hidden=False,
                                              grant_type='matic').count()
    change_count = Grant.objects.filter(network=network,
                                        hidden=False,
                                        grant_type='change').count()
    all_grants_count = Grant.objects.filter(network=network,
                                            hidden=False).count()

    categories = [
        _category[0] for _category in basic_grant_categories(grant_type)
    ]

    grant_types = [
        {
            'label': 'Tech',
            'keyword': 'tech',
            'count': tech_grants_count
        },
        {
            'label': 'Community',
            'keyword': 'media',
            'count': media_grants_count
        },
        #        {'label': 'Health', 'keyword': 'health', 'count': health_grants_count},
        #        {'label': 'Matic', 'keyword': 'matic', 'count': matic_grants_count},
        {
            'label': 'Crypto for Black Lives',
            'keyword': 'change',
            'count': change_count
        },
    ]

    sub_categories = []
    for _keyword in [grant_type['keyword'] for grant_type in grant_types]:
        sub_category = {}
        sub_category[_keyword] = [
            tuple[0] for tuple in basic_grant_categories(_keyword)
        ]
        sub_categories.append(sub_category)

    title = matching_live + str(_('Grants'))
    has_real_grant_type = grant_type and grant_type != 'activity'
    grant_type_title_if_any = grant_type.title() if has_real_grant_type else ''
    if grant_type_title_if_any == "Media":
        grant_type_title_if_any = "Community"
    if grant_type_title_if_any == "Change":
        grant_type_title_if_any = "Crypto for Black Lives"
    grant_type_gfx_if_any = grant_type if has_real_grant_type else 'total'
    if has_real_grant_type:
        title = f"{matching_live} {grant_type_title_if_any.title()} {category.title()} Grants"
    if grant_type == 'stats':
        title = f"Round {clr_round} Stats"
    cht = []
    chart_list = ''
    try:
        what = 'all_grants'
        pinned = PinnedPost.objects.get(what=what)
    except PinnedPost.DoesNotExist:
        pinned = None

    prev_grants = Grant.objects.none()
    if request.user.is_authenticated:
        prev_grants = request.user.profile.grant_contributor.filter(
            created_on__gt=last_round_start,
            created_on__lt=last_round_end).values_list('grant', flat=True)
        prev_grants = Grant.objects.filter(pk__in=prev_grants)

    params = {
        'active':
        'grants_landing',
        'title':
        title,
        'sort':
        sort,
        'network':
        network,
        'keyword':
        keyword,
        'type':
        grant_type,
        'round_end':
        round_end,
        'next_round_start':
        next_round_start,
        'after_that_next_round_begin':
        after_that_next_round_begin,
        'all_grants_count':
        all_grants_count,
        'now':
        timezone.now(),
        'mid_back':
        mid_back,
        'cht':
        cht,
        'chart_list':
        chart_list,
        'bottom_back':
        bottom_back,
        'clr_matching_banners_style':
        clr_matching_banners_style,
        'categories':
        categories,
        'sub_categories':
        sub_categories,
        'prev_grants':
        prev_grants,
        'grant_types':
        grant_types,
        'current_partners_fund':
        current_partners_fund,
        'current_partners':
        current_partners,
        'past_partners':
        past_partners,
        'card_desc':
        f'{live_now}',
        'avatar_url':
        request.build_absolute_uri(
            static('v2/images/twitter_cards/tw_cards-03.png')),
        'card_type':
        'summary_large_image',
        'avatar_height':
        1097,
        'avatar_width':
        1953,
        'grants':
        grants,
        'what':
        what,
        'can_pin':
        can_pin(request, what),
        'pinned':
        pinned,
        'target':
        f'/activity?what=all_grants',
        'bg':
        bg,
        'keywords':
        get_keywords(),
        'grant_amount':
        grant_amount,
        'total_clr_pot':
        total_clr_pot,
        'clr_active':
        clr_active,
        'sort_by_index':
        sort_by_index,
        'clr_round':
        clr_round,
        'show_past_clr':
        show_past_clr,
        'is_staff':
        request.user.is_staff,
        'selected_category':
        category,
        'profile':
        profile
    }

    # log this search, it might be useful for matching purposes down the line
    if keyword:
        try:
            SearchHistory.objects.update_or_create(search_type='grants',
                                                   user=request.user,
                                                   data=request.GET,
                                                   ip_address=get_ip(request))
        except Exception as e:
            logger.debug(e)
            pass

    response = TemplateResponse(request, 'grants/index.html', params)
    response['X-Frame-Options'] = 'SAMEORIGIN'
    return response