Example #1
0
    def get_converted_amount(self, ignore_gitcoin_fee=False):
        amount = self.amount_per_period if ignore_gitcoin_fee else self.amount_per_period_minus_gas_price
        try:
            if self.token_symbol == "ETH" or self.token_symbol == "WETH":
                return Decimal(float(amount) * float(eth_usd_conv_rate()))
            else:
                value_token_to_eth = Decimal(convert_amount(
                    amount,
                    self.token_symbol,
                    "ETH")
                )

            value_eth_to_usdt = Decimal(eth_usd_conv_rate())
            value_usdt = value_token_to_eth * value_eth_to_usdt
            return value_usdt

        except ConversionRateNotFoundError as e:
            try:
                return Decimal(convert_amount(
                    amount,
                    self.token_symbol,
                    "USDT"))
            except ConversionRateNotFoundError as no_conversion_e:
                logger.info(no_conversion_e)
                return None
Example #2
0
def cancel_bounty(request, pk):
    """Kill an expired bounty.

    Args:
        pk (int): The primary key of the bounty to be cancelled.

    Raises:
        Http404: The exception is raised if no associated Bounty is found.

    Returns:
        TemplateResponse: The cancel bounty view.

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

    params = {
        'bounty': bounty,
        'title': _('Kill Bounty'),
        'active': 'kill_bounty',
        'recommend_gas_price': recommend_min_gas_price_to_confirm_in_time(confirm_time_minutes_target),
        'eth_usd_conv_rate': eth_usd_conv_rate(),
        'conf_time_spread': conf_time_spread(),
    }

    return TemplateResponse(request, 'kill_bounty.html', params)
Example #3
0
def increase_bounty(request, pk):
    """Increase a bounty as the funder.

    Args:
        pk (int): The primary key of the bounty to be increased.

    Raises:
        Http404: The exception is raised if no associated Bounty is found.

    Returns:
        TemplateResponse: The increase bounty view.

    """
    try:
        bounty = Bounty.objects.get(pk=pk)
    except (Bounty.DoesNotExist, ValueError):
        raise Http404
    except ValueError:
        raise Http404

    params = {
        'bounty': bounty,
        'title': _('Increase Bounty'),
        'active': 'increase_bounty',
        'recommend_gas_price': recommend_min_gas_price_to_confirm_in_time(confirm_time_minutes_target),
        'eth_usd_conv_rate': eth_usd_conv_rate(),
        'conf_time_spread': conf_time_spread(),
    }

    return TemplateResponse(request, 'increase_bounty.html', params)
Example #4
0
def fulfill_bounty(request, pk):
    """Fulfill a bounty.

    Args:
        pk (int): The primary key of the bounty to be fulfilled.

    Raises:
        Http404: The exception is raised if no associated Bounty is found.

    Returns:
        TemplateResponse: The fulfill bounty view.

    """
    try:
        bounty = Bounty.objects.get(pk=pk)
    except (Bounty.DoesNotExist, ValueError):
        raise Http404
    except ValueError:
        raise Http404

    is_user_authenticated = request.user.is_authenticated
    params = {
        'bounty': bounty,
        'githubUsername': request.GET.get('githubUsername'),
        'title': _('Submit Work'),
        'active': 'fulfill_bounty',
        'recommend_gas_price': recommend_min_gas_price_to_confirm_in_time(confirm_time_minutes_target),
        'eth_usd_conv_rate': eth_usd_conv_rate(),
        'conf_time_spread': conf_time_spread(),
        'email': request.user.email if is_user_authenticated else '',
        'handle': request.user.username if is_user_authenticated else '',
    }

    return TemplateResponse(request, 'fulfill_bounty.html', params)
Example #5
0
def accept_bounty(request, pk):
    """Process the bounty.

    Args:
        pk (int): The primary key of the bounty to be accepted.

    Raises:
        Http404: The exception is raised if no associated Bounty is found.

    Returns:
        TemplateResponse: The accept bounty view.

    """
    try:
        bounty = Bounty.objects.get(pk=pk)
    except (Bounty.DoesNotExist, ValueError):
        raise Http404
    except ValueError:
        raise Http404

    params = {
        'bounty': bounty,
        'fulfillment_id': request.GET.get('id'),
        'fulfiller_address': request.GET.get('address'),
        'title': _('Process Issue'),
        'recommend_gas_price': recommend_min_gas_price_to_confirm_in_time(confirm_time_minutes_target),
        'eth_usd_conv_rate': eth_usd_conv_rate(),
        'conf_time_spread': conf_time_spread(),
    }

    return TemplateResponse(request, 'process_bounty.html', params)
Example #6
0
def increase_bounty(request):
    """Increase a bounty (funder)"""
    issue_url = request.GET.get('source')
    params = {
        'issue_url':
        issue_url,
        'title':
        _('Increase Bounty'),
        'active':
        'increase_bounty',
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(
            confirm_time_minutes_target),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
    }

    try:
        bounties = Bounty.objects.current().filter(github_url=issue_url)
        if bounties:
            bounty = bounties.order_by('pk').first()
            params['standard_bounties_id'] = bounty.standard_bounties_id
            params['bounty_owner_address'] = bounty.bounty_owner_address
            params['value_in_token'] = bounty.value_in_token
            params['token_address'] = bounty.token_address
    except Bounty.DoesNotExist:
        pass
    except Exception as e:
        print(e)
        logging.error(e)

    return TemplateResponse(request, 'increase_bounty.html', params)
Example #7
0
def fulfill_bounty(request):
    """Fulfill a bounty."""
    is_user_authenticated = request.user.is_authenticated
    params = {
        'issueURL':
        request.GET.get('source'),
        'githubUsername':
        request.GET.get('githubUsername'),
        'title':
        _('Submit Work'),
        'active':
        'fulfill_bounty',
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(
            confirm_time_minutes_target),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
        'email':
        request.user.email if is_user_authenticated else '',
        'handle':
        request.user.username if is_user_authenticated else '',
    }

    return TemplateResponse(request, 'fulfill_bounty.html', params)
Example #8
0
def get_context(ref_object=None,
                github_username='',
                user=None,
                confirm_time_minutes_target=4,
                active='',
                title='',
                update=None):
    """Get the context dictionary for use in view."""
    context = {
        'githubUsername':
        github_username,  # TODO: Deprecate this field.
        'active':
        active,
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(
            confirm_time_minutes_target),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
        'email':
        getattr(user, 'email', ''),
        'handle':
        getattr(user, 'username', ''),
        'title':
        title,
    }
    if ref_object is not None:
        context.update(
            {f'{ref_object.__class__.__name__}'.lower(): ref_object})
    if update is not None and isinstance(update, dict):
        context.update(update)
    return context
Example #9
0
def subscription_cancel(request, grant_id, grant_slug, subscription_id):
    """Handle the cancellation of a grant subscription."""
    subscription = Subscription.objects.select_related('grant').get(pk=subscription_id)
    grant = getattr(subscription, 'grant', None)
    now = datetime.datetime.now()
    profile = get_profile(request)

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

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

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

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

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

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

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

    return TemplateResponse(request, 'grants/cancel.html', params)
Example #10
0
def fulfill_bounty(request):
    """Claim a legacy bounty."""
    params = {
        'issueURL':
        request.GET.get('source'),
        'title':
        'Fulfill Issue',
        'active':
        'fulfill_bounty',
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(
            confirm_time_minutes_target),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
        'handle':
        request.session.get('handle', ''),
        'email':
        request.session.get('email', ''),
        'is_legacy':
        True,
    }

    return TemplateResponse(request, 'fulfill_bounty.html', params)
Example #11
0
File: views.py Project: bakaoh/web
def new_bounty(request):
    """Create a new bounty."""
    issue_url = request.GET.get('source') or request.GET.get('url', '')
    params = {
        'issueURL':
        issue_url,
        'amount':
        request.GET.get('amount'),
        'active':
        'submit_bounty',
        'title':
        'Create Funded Issue',
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(
            confirm_time_minutes_target),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
        'from_email':
        request.session.get('email', ''),
        'from_handle':
        request.session.get('handle', ''),
        'newsletter_headline':
        'Be the first to know about new funded issues.'
    }

    return TemplateResponse(request, 'submit_bounty.html', params)
Example #12
0
File: views.py Project: bakaoh/web
def fulfill_bounty(request):
    """Fulfill a bounty."""
    params = {
        'issueURL':
        request.GET.get('source'),
        'githubUsername':
        request.GET.get('githubUsername'),
        'title':
        'Submit Work',
        'active':
        'fulfill_bounty',
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(
            confirm_time_minutes_target),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
        'handle':
        request.session.get('handle', ''),
        'email':
        request.session.get('email', '')
    }

    return TemplateResponse(request, 'fulfill_bounty.html', params)
Example #13
0
def get_converted_amount(amount, token_symbol):
    try:
        if token_symbol == "ETH" or token_symbol == "WETH":
            return Decimal(float(amount) * float(eth_usd_conv_rate()))
        else:
            value_token_to_eth = Decimal(
                convert_amount(amount, token_symbol, "ETH"))

        value_eth_to_usdt = Decimal(eth_usd_conv_rate())
        value_usdt = value_token_to_eth * value_eth_to_usdt
        return value_usdt

    except ConversionRateNotFoundError as e:
        try:
            return Decimal(convert_amount(amount, token_symbol, "USDT"))
        except ConversionRateNotFoundError as no_conversion_e:
            logger.info(no_conversion_e)
            return None
Example #14
0
def kill_bounty(request):
    """Kill an expired bounty."""
    params = {
        'issueURL': request.GET.get('source'),
        'title': 'Kill Bounty',
        'active': 'kill_bounty',
        'recommend_gas_price': recommend_min_gas_price_to_confirm_in_time(confirm_time_minutes_target),
        'eth_usd_conv_rate': eth_usd_conv_rate(),
        'conf_time_spread': conf_time_spread(),
    }

    return TemplateResponse(request, 'kill_bounty.html', params)
Example #15
0
def process_bounty(request):
    """Process the bounty."""
    params = {
        'issueURL': request.GET.get('source'),
        'fulfillment_id': request.GET.get('id'),
        'fulfiller_address': request.GET.get('address'),
        'title': 'Process Issue',
        'recommend_gas_price': recommend_min_gas_price_to_confirm_in_time(confirm_time_minutes_target),
        'eth_usd_conv_rate': eth_usd_conv_rate(),
        'conf_time_spread': conf_time_spread(),
    }

    return TemplateResponse(request, 'process_bounty.html', params)
Example #16
0
    def get_converted_amount(self):
        try:
            if self.token_symbol == "ETH" or self.token_symbol == "WETH":
                return Decimal(self.amount_per_period * eth_usd_conv_rate())
            else:
                value_token_to_eth = Decimal(convert_amount(
                    self.amount_per_period,
                    self.token_symbol,
                    "ETH")
                )

            value_eth_to_usdt = Decimal(eth_usd_conv_rate())
            value_usdt = value_token_to_eth * value_eth_to_usdt
            return value_usdt

        except ConversionRateNotFoundError as e:
            try:
                return Decimal(convert_amount(
                    self.amount_per_period,
                    self.token_symbol,
                    "USDT"))
            except ConversionRateNotFoundError as no_conversion_e:
                logger.info(no_conversion_e)
                return None
Example #17
0
def clawback_expired_bounty(request):

    params = {
        'issueURL':
        request.GET.get('source'),
        'title':
        'Clawback Expired Issue',
        'active':
        'clawback_expired_bounty',
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(
            confirm_time_minutes_target),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
    }

    return TemplateResponse(request, 'clawback_expired_bounty.html', params)
Example #18
0
def grant_new_whitelabel(request):
    """Create a new grant, with a branded creation form for specific tribe"""

    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-whitelabel.html', params)
Example #19
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)
Example #20
0
def new_bounty(request):
    """Create a new bounty."""
    params = {
        'issueURL':
        request.GET.get('source'),
        'active':
        'submit_bounty',
        'title':
        'Create Funded Issue',
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(
            confirm_time_minutes_target),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
        'from_email':
        request.session.get('email', ''),
        'from_handle':
        request.session.get('handle', '')
    }

    return TemplateResponse(request, 'submit_bounty.html', params)
Example #21
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)
Example #22
0
def grant_new_v0(request):
    """Create a v0 version of a grant contract."""
    profile = get_profile(request)

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

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

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

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

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

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

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

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


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

    return TemplateResponse(request, 'grants/newv0.html', params)
Example #23
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)
Example #24
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)
Example #25
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)
Example #26
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)
Example #27
0
File: views.py Project: rmshea/web
def grant_fund(request, grant_id, grant_slug):
    """Handle grant funding."""
    try:
        grant = Grant.objects.get(pk=grant_id, slug=grant_slug)
    except Grant.DoesNotExist:
        raise Http404

    profile = get_profile(request)

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

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

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

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

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

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

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

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

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

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

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

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

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

    splitter_contract_address = settings.SPLITTER_CONTRACT_ADDRESS

    params = {
        'active':
        'fund_grant',
        'title':
        _('Fund Grant'),
        'card_desc':
        _('Provide sustainable funding for Open Source with Gitcoin Grants'),
        'subscription': {},
        'grant_has_no_token':
        True if grant.token_address
        == '0x0000000000000000000000000000000000000000' else False,
        'grant':
        grant,
        'keywords':
        get_keywords(),
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(4),
        'recommend_gas_price_slow':
        recommend_min_gas_price_to_confirm_in_time(120),
        'recommend_gas_price_avg':
        recommend_min_gas_price_to_confirm_in_time(15),
        'recommend_gas_price_fast':
        recommend_min_gas_price_to_confirm_in_time(1),
        'eth_usd_conv_rate':
        eth_usd_conv_rate(),
        'conf_time_spread':
        conf_time_spread(),
        'gas_advisories':
        gas_advisories(),
        'splitter_contract_address':
        settings.SPLITTER_CONTRACT_ADDRESS,
        'gitcoin_donation_address':
        settings.GITCOIN_DONATION_ADDRESS
    }
    return TemplateResponse(request, 'grants/fund.html', params)
Example #28
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)
Example #29
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)
Example #30
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)