示例#1
0
def send_tip_3(request):
    """Handle the third stage of sending a tip (the POST).

    Returns:
        JsonResponse: response with success state.

    """
    response = {
        'status': 'OK',
        'message': _('Tip Created'),
    }

    is_user_authenticated = request.user.is_authenticated
    from_username = request.user.username if is_user_authenticated else ''
    primary_from_email = request.user.email if is_user_authenticated else ''
    access_token = request.user.profile.get_access_token() if is_user_authenticated and request.user.profile else ''

    params = json.loads(request.body)

    to_username = params['username'].lstrip('@')
    to_emails = get_emails_by_category(to_username)
    primary_email = ''

    if params.get('email'):
        primary_email = params['email']
    elif to_emails.get('primary', None):
        primary_email = to_emails['primary']
    elif to_emails.get('github_profile', None):
        primary_email = to_emails['github_profile']
    else:
        if len(to_emails.get('events', None)):
            primary_email = to_emails['events'][0]
        else:
            print("TODO: no email found.  in the future, we should handle this case better because it's GOING to end up as a support request")
    if primary_email and isinstance(primary_email, list):
        primary_email = primary_email[0]

    # If no primary email in session, try the POST data. If none, fetch from GH.
    if params.get('fromEmail'):
        primary_from_email = params['fromEmail']
    elif access_token and not primary_from_email:
        primary_from_email = get_github_primary_email(access_token)

    expires_date = timezone.now() + timezone.timedelta(seconds=params['expires_date'])

    # metadata
    metadata = params['metadata']
    metadata['user_agent'] = request.META.get('HTTP_USER_AGENT', '')

    # db mutations
    tip = Tip.objects.create(
        primary_email=primary_email,
        emails=to_emails,
        tokenName=params['tokenName'],
        amount=params['amount'],
        comments_priv=params['comments_priv'],
        comments_public=params['comments_public'],
        ip=get_ip(request),
        expires_date=expires_date,
        github_url=params['github_url'],
        from_name=params['from_name'] if params['from_name'] != 'False' else '',
        from_email=params['from_email'],
        from_username=from_username,
        username=params['username'],
        network=params.get('network', 'unknown'),
        tokenAddress=params['tokenAddress'],
        from_address=params['from_address'],
        is_for_bounty_fulfiller=params['is_for_bounty_fulfiller'],
        metadata=metadata,
        recipient_profile=get_profile(to_username),
        sender_profile=get_profile(from_username),
    )

    return JsonResponse(response)
示例#2
0
def receive_bulk(request, secret):

    coupons = BulkTransferCoupon.objects.filter(secret=secret)
    if not coupons.exists():
        raise Http404

    coupon = coupons.first()
    _class = request.GET.get('class', '')
    if coupon.num_uses_remaining <= 0:
        messages.info(request, f'Sorry but the coupon for a free kudos has been used already.  Contact the person who sent you the coupon link, or you can still purchase one on this page.')
        return redirect(coupon.token.url)

    error = False
    if request.POST:
        if request.user.is_anonymous:
            error = "You must login."
        if not error:
            submit_later = (recommend_min_gas_price_to_confirm_in_time(1)) > 10 and not coupon.is_paid_right_now
            submit_later = False
            success, error, _ = redeem_bulk_coupon(coupon, request.user.profile, request.POST.get('forwarding_address'), get_ip(request), request.POST.get('save_addr'), submit_later=submit_later)
        if error:
            messages.error(request, error)

    kudos_transfer = None
    if request.user.is_authenticated:
        redemptions = BulkTransferRedemption.objects.filter(redeemed_by=request.user.profile, coupon=coupon)
        if redemptions.exists():
            kudos_transfer = redemptions.first().kudostransfer

    title = f"Redeem {coupon.token.humanized_name} Kudos from @{coupon.sender_profile.handle}"
    desc = f"This Kudos has been AirDropped to you.  About this Kudos: {coupon.token.description}"
    tweet_text = f"I just got a {coupon.token.humanized_name} Kudos on @gitcoin.  " if not request.GET.get('tweet', None) else request.GET.get('tweet')
    gas_amount = round(0.00035 * 1.3 * float(recommend_min_gas_price_to_confirm_in_time(1)), 4)
    params = {
        'title': title,
        'card_title': title,
        'card_desc': desc,
        'error': error,
        'avatar_url': coupon.token.img_url,
        'coupon': coupon,
        'user': request.user,
        'class': _class,
        'gas_amount': gas_amount,
        'is_authed': request.user.is_authenticated,
        'kudos_transfer': kudos_transfer,
        'tweet_text': urllib.parse.quote_plus(tweet_text),
        'tweet_url': coupon.token.url if not request.GET.get('tweet_url') else request.GET.get('tweet_url'),
    }
    return TemplateResponse(request, 'transaction/receive_bulk.html', params)
示例#3
0
def send_tip_3(request):
    """Handle the third stage of sending a tip (the POST)

    Returns:
        JsonResponse: response with success state.

    """
    response = {
        'status': 'OK',
        'message': _('Tip Created'),
    }

    is_user_authenticated = request.user.is_authenticated
    from_username = request.user.username if is_user_authenticated else ''
    primary_from_email = request.user.email if is_user_authenticated else ''
    access_token = request.user.profile.get_access_token(
    ) if is_user_authenticated else ''
    to_emails = []

    params = json.loads(request.body)

    to_username = params['username'].lstrip('@')
    to_emails = get_emails_master(to_username)

    if params.get('email'):
        to_emails.append(params['email'])

    # If no primary email in session, try the POST data. If none, fetch from GH.
    if params.get('fromEmail'):
        primary_from_email = params['fromEmail']
    elif access_token and not primary_from_email:
        primary_from_email = get_github_primary_email(access_token)

    to_emails = list(set(to_emails))
    expires_date = timezone.now() + timezone.timedelta(
        seconds=params['expires_date'])

    # db mutations
    tip = Tip.objects.create(
        emails=to_emails,
        tokenName=params['tokenName'],
        amount=params['amount'],
        comments_priv=params['comments_priv'],
        comments_public=params['comments_public'],
        ip=get_ip(request),
        expires_date=expires_date,
        github_url=params['github_url'],
        from_name=params['from_name'],
        from_email=params['from_email'],
        from_username=from_username,
        username=params['username'],
        network=params['network'],
        tokenAddress=params['tokenAddress'],
        from_address=params['from_address'],
        is_for_bounty_fulfiller=params['is_for_bounty_fulfiller'],
        metadata=params['metadata'],
        recipient_profile=get_profile(to_username),
        sender_profile=get_profile(from_username),
    )

    is_over_tip_tx_limit = False
    is_over_tip_weekly_limit = False
    max_per_tip = request.user.profile.max_tip_amount_usdt_per_tx if request.user.is_authenticated and request.user.profile else 500
    if tip.value_in_usdt_now:
        is_over_tip_tx_limit = tip.value_in_usdt_now > max_per_tip
        if request.user.is_authenticated and request.user.profile:
            tips_last_week_value = tip.value_in_usdt_now
            tips_last_week = Tip.objects.exclude(txid='').filter(
                sender_profile=get_profile(from_username),
                created_on__gt=timezone.now() - timezone.timedelta(days=7))
            for this_tip in tips_last_week:
                if this_tip.value_in_usdt_now:
                    tips_last_week_value += this_tip.value_in_usdt_now
            is_over_tip_weekly_limit = tips_last_week_value > request.user.profile.max_tip_amount_usdt_per_week
    if is_over_tip_tx_limit:
        response['status'] = 'error'
        response['message'] = _(
            'This tip is over the per-transaction limit of $') + str(
                max_per_tip) + (
                    '.  Please try again later or contact support.')
    elif is_over_tip_weekly_limit:
        response['status'] = 'error'
        response['message'] = _(
            'You are over the weekly tip send limit of $') + str(
                request.user.profile.max_tip_amount_usdt_per_week) + (
                    '.  Please try again later or contact support.')
    return JsonResponse(response)
示例#4
0
def account_settings(request):
    """Display and save user's Account settings.

    Returns:
        TemplateResponse: The user's Account settings template response.

    """
    msg = ''
    profile, es, user, is_logged_in = settings_helper_get_auth(request)

    if not user or not profile or not is_logged_in:
        login_redirect = redirect('/login/github?next=' +
                                  request.get_full_path())
        return login_redirect

    if request.POST:

        if 'preferred_payout_address' in request.POST.keys():
            profile.preferred_payout_address = request.POST.get(
                'preferred_payout_address', '')
            profile.save()
            msg = _('Updated your Address')
        elif request.POST.get('disconnect', False):
            profile.github_access_token = ''
            profile = record_form_submission(request, profile,
                                             'account-disconnect')
            profile.email = ''
            profile.save()
            create_user_action(profile.user, 'account_disconnected', request)
            messages.success(
                request, _('Your account has been disconnected from Github'))
            logout_redirect = redirect(reverse('logout') + '?next=/')
            return logout_redirect
        elif request.POST.get('delete', False):

            # remove profile
            profile.hide_profile = True
            profile = record_form_submission(request, profile,
                                             'account-delete')
            profile.email = ''
            profile.save()

            # remove email
            try:
                client = MailChimp(mc_user=settings.MAILCHIMP_USER,
                                   mc_api=settings.MAILCHIMP_API_KEY)
                result = client.search_members.get(query=es.email)
                subscriber_hash = result['exact_matches']['members'][0]['id']
                client.lists.members.delete(
                    list_id=settings.MAILCHIMP_LIST_ID,
                    subscriber_hash=subscriber_hash,
                )
            except Exception as e:
                logger.exception(e)
            if es:
                es.delete()
            request.user.delete()
            AccountDeletionRequest.objects.create(handle=profile.handle,
                                                  profile={
                                                      'ip': get_ip(request),
                                                  })
            profile.delete()
            messages.success(request, _('Your account has been deleted.'))
            logout_redirect = redirect(reverse('logout') + '?next=/')
            return logout_redirect
        else:
            msg = _('Error: did not understand your request')

    context = {
        'is_logged_in': is_logged_in,
        'nav': 'internal',
        'active': '/settings/account',
        'title': _('Account Settings'),
        'navs': get_settings_navs(request),
        'es': es,
        'profile': profile,
        'msg': msg,
    }
    return TemplateResponse(request, 'settings/account.html', context)
示例#5
0
    def get_queryset(self):
        """Get the queryset for Bounty.

        Returns:
            QuerySet: The Bounty queryset.

        """
        param_keys = self.request.query_params.keys()
        queryset = Bounty.objects.prefetch_related(
            'fulfillments', 'interested', 'interested__profile', 'activities', 'event')
        if 'not_current' not in param_keys:
            queryset = queryset.current()

        queryset = queryset.order_by('-web3_created')

        # filtering
        event_tag = self.request.query_params.get('event_tag', '')
        if event_tag:
            if event_tag == 'all':
                pass
            else:
                try:
                    evt = HackathonEvent.objects.filter(slug__iexact=event_tag).latest('id')
                    queryset = queryset.filter(event__pk=evt.pk)
                except HackathonEvent.DoesNotExist:
                    return Bounty.objects.none()
        # else:
        #     queryset = queryset.filter(event=None)

        for key in ['raw_data', 'experience_level', 'project_length', 'bounty_type', 'bounty_categories',
                    'bounty_owner_address', 'idx_status', 'network', 'bounty_owner_github_username',
                    'standard_bounties_id', 'permission_type', 'project_type', 'pk']:
            if key in param_keys:
                # special hack just for looking up bounties posted by a certain person
                request_key = key if key != 'bounty_owner_address' else 'coinbase'
                val = self.request.query_params.get(request_key, '')

                values = val.strip().split(',')
                values = [value for value in values if value and val.strip()]
                if values:
                    _queryset = queryset.none()
                    for value in values:
                        args = {}
                        args[f'{key}__icontains'] = value.strip()
                        _queryset = _queryset | queryset.filter(**args)
                    queryset = _queryset

        if 'reserved_for_user_handle' in param_keys:
            handle = self.request.query_params.get('reserved_for_user_handle', '')
            if handle:
                try:
                    profile = Profile.objects.filter(handle=handle.lower()).first()
                    queryset = queryset.filter(bounty_reserved_for_user=profile)
                except:
                    logger.warning(f'reserved_for_user_handle: Unknown handle: ${handle}')

        # filter by PK
        if 'pk__gt' in param_keys:
            queryset = queryset.filter(pk__gt=self.request.query_params.get('pk__gt'))

        # Filter by a list of PKs
        if 'pk__in' in param_keys:
            try:
                list_of_pks = self.request.query_params.get('pk__in').split(',')
                queryset = queryset.filter(pk__in=list_of_pks)
            except Exception:
                pass

        # filter by standard_bounties_id
        if 'standard_bounties_id__in' in param_keys:
            statuses = self.request.query_params.get('standard_bounties_id__in').split(',')
            queryset = queryset.filter(standard_bounties_id__in=statuses)

        # filter by statuses
        if 'status__in' in param_keys:
            statuses = self.request.query_params.get('status__in').split(',')
            queryset = queryset.filter(idx_status__in=statuses)

        applicants = self.request.query_params.get('applicants')
        if applicants == '0':
            queryset = queryset.annotate(
                interested_count=Count("interested")
            ).filter(interested_count=0)
        elif applicants == '1-5':
            queryset = queryset.annotate(
                interested_count=Count("interested")
            ).filter(interested_count__gte=1).filter(interested_count__lte=5)

        # filter by who is interested
        if 'started' in param_keys:
            queryset = queryset.filter(interested__profile__handle__in=[self.request.query_params.get('started')])

        # filter by is open or not
        if 'is_open' in param_keys:
            queryset = queryset.filter(is_open=self.request.query_params.get('is_open', '').lower() == 'true')
            queryset = queryset.filter(expires_date__gt=datetime.now())

        # filter by urls
        if 'github_url' in param_keys:
            urls = self.request.query_params.get('github_url').split(',')
            queryset = queryset.filter(github_url__in=urls)

        # filter by orgs
        if 'org' in param_keys:
            val = self.request.query_params.get('org', '')
            values = val.strip().split(',')
            values = [value for value in values if value and val.strip()]
            if values:
                _queryset = queryset.none()
                for value in values:
                    org = value.strip()
                    _queryset = _queryset | queryset.filter(github_url__icontains=f'https://github.com/{org}')
                queryset = _queryset

        # Retrieve all fullfilled bounties by fulfiller_username
        if 'fulfiller_github_username' in param_keys:
            queryset = queryset.filter(
                fulfillments__profile__handle__iexact=self.request.query_params.get('fulfiller_github_username')
            )

        # Retrieve all DONE fullfilled bounties by fulfiller_username
        if 'fulfiller_github_username_done' in param_keys:
            queryset = queryset.filter(
                fulfillments__profile__handle__iexact=self.request.query_params.get('fulfiller_github_username'),
                fulfillments__accepted=True,
            )

        # Retrieve all interested bounties by profile handle
        if 'interested_github_username' in param_keys:
            queryset = queryset.filter(
                interested__profile__handle=self.request.query_params.get('interested_github_username').lower()
            )

        # Retrieve all mod bounties.
        # TODO: Should we restrict this to staff only..? Technically I don't think we're worried about that atm?
        if 'moderation_filter' in param_keys:
            mod_filter = self.request.query_params.get('moderation_filter')
            if mod_filter == 'needs_review':
                queryset = queryset.needs_review()
            elif mod_filter == 'warned':
                queryset = queryset.warned()
            elif mod_filter == 'escalated':
                queryset = queryset.escalated()
            elif mod_filter == 'closed_on_github':
                queryset = queryset.closed()
            elif mod_filter == 'hidden':
                queryset = queryset.hidden()
            elif mod_filter == 'not_started':
                queryset = queryset.not_started()

        # All Misc Api things
        if 'misc' in param_keys:
            if self.request.query_params.get('misc') == 'hiring':
                queryset = queryset.exclude(attached_job_description__isnull=True).exclude(attached_job_description='')

        if 'event' in param_keys:
            queryset = queryset.filter(
                repo_type=self.request.query_params.get('event'),
            )

        # Keyword search to search all comma separated keywords
        queryset_original = queryset
        if 'keywords' in param_keys:
            for index, keyword in enumerate(self.request.query_params.get('keywords').split(',')):
                if index == 0:
                    queryset = queryset_original.keyword(keyword)
                else:
                    queryset |= queryset_original.keyword(keyword)

        if 'is_featured' in param_keys:
            queryset = queryset.filter(
                is_featured=self.request.query_params.get('is_featured'),
                is_open=True,
            )

        if 'repo_type' in param_keys:
            queryset = queryset.filter(
                repo_type=self.request.query_params.get('repo_type'),
            )
        # order
        order_by = self.request.query_params.get('order_by')
        if order_by and order_by != 'null':
            if order_by == 'recently_marketed':
                queryset = queryset.order_by(F('last_remarketed').desc(nulls_last = True), '-web3_created')
            else:
                queryset = queryset.order_by(order_by)

        queryset = queryset.distinct()

        # offset / limit
        if 'is_featured' not in param_keys:
            limit = int(self.request.query_params.get('limit', 5))
            max_bounties = 100
            if limit > max_bounties:
                limit = max_bounties
            offset = self.request.query_params.get('offset', 0)
            if limit:
                start = int(offset)
                end = start + int(limit)
                queryset = queryset[start:end]

        data = dict(self.request.query_params)
        data.pop('is_featured', None)

        # save search history, but only not is_featured
        if 'is_featured' not in param_keys:
            if self.request.user and self.request.user.is_authenticated:
                data['nonce'] = int(time.time()  * 1000000)
                try:
                    SearchHistory.objects.update_or_create(
                        search_type='bounty',
                        user=self.request.user,
                        data=data,
                        ip_address=get_ip(self.request)
                    )
                except Exception as e:
                    logger.debug(e)
                    pass

        # increment view counts
        pks = [ele.pk for ele in queryset]
        if len(pks):
            view_type = 'individual' if len(pks) == 1 else 'list'
            increment_view_count.delay(pks, queryset[0].content_type, self.request.user.id, view_type)

        return queryset
示例#6
0
文件: views.py 项目: reyadrahman/web
def send_tip_2(request):

    if request.body != '':
        status = 'OK'
        message = 'Notification has been sent'
        params = json.loads(request.body)
        emails = []

        #basic validation
        username = params['username']

        #get emails
        if params['email']:
            emails.append(params['email'])
        gh_user = get_github_user(username)
        user_full_name = gh_user['name']
        if gh_user.get('email', False):
            emails.append(gh_user['email'])
        gh_user_events = get_github_user(username, '/events/public')
        for event in gh_user_events:
            commits = event.get('payload', {}).get('commits', [])
            for commit in commits:
                email = commit.get('author', {}).get('email', None)
                #print(event['actor']['display_login'].lower() == username.lower())
                #print(commit['author']['name'].lower() == user_full_name.lower())
                #print('========')
                if email and \
                    event['actor']['display_login'].lower() == username.lower() and \
                    commit['author']['name'].lower() == user_full_name.lower() and \
                    'noreply.github.com' not in email and \
                    email not in emails:
                    emails.append(email)
        expires_date = timezone.now() + timezone.timedelta(
            seconds=params['expires_date'])

        #db mutations
        tip = Tip.objects.create(
            emails=emails,
            url=params['url'],
            tokenName=params['tokenName'],
            amount=params['amount'],
            comments_priv=params['comments_priv'],
            comments_public=params['comments_public'],
            ip=get_ip(request),
            expires_date=expires_date,
            github_url=params['github_url'],
            from_name=params['from_name'],
            from_email=params['from_email'],
            username=params['username'],
            network=params['network'],
            tokenAddress=params['tokenAddress'],
            txid=params['txid'],
        )

        #notifications
        did_post_to_github = maybe_market_tip_to_github(tip)
        maybe_market_tip_to_slack(tip, 'new_tip', tip.txid)
        tip_email(tip, set(emails), True)
        if len(emails) == 0:
            status = 'error'
            message = 'Uh oh! No email addresses for this user were found via Github API.  Youll have to let the tipee know manually about their tip.'

        #http response
        response = {
            'status': status,
            'message': message,
        }
        return JsonResponse(response)

    params = {
        'issueURL':
        request.GET.get('source'),
        'class':
        'send2',
        'title':
        'Send Tip',
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(
            confirm_time_minutes_target),
    }

    return TemplateResponse(request, 'yge/send2.html', params)
示例#7
0
文件: views.py 项目: mkosowsk/web
def send_tip_2(request):
    """Handle the second stage of sending a tip.

    TODO:
        * Convert this view-based logic to a django form.

    Returns:
        JsonResponse: If submitting tip, return response with success state.
        TemplateResponse: Render the submission form.

    """
    from_username = request.session.get('handle', '')
    primary_from_email = request.session.get('email', '')
    access_token = request.session.get('access_token')
    to_emails = []

    if request.body:
        # http response
        response = {
            'status': 'OK',
            'message': 'Notification has been sent',
        }
        params = json.loads(request.body)

        to_username = params['username'].lstrip('@')
        try:
            to_profile = Profile.objects.get(handle__iexact=to_username)
            if to_profile.email:
                to_emails.append(to_profile.email)
            if to_profile.github_access_token:
                to_emails = get_github_emails(to_profile.github_access_token)
        except Profile.DoesNotExist:
            pass

        if params.get('email'):
            to_emails.append(params['email'])

        # If no primary email in session, try the POST data. If none, fetch from GH.
        if params.get('fromEmail'):
            primary_from_email = params['fromEmail']
        elif access_token and not primary_from_email:
            primary_from_email = get_github_primary_email(access_token)

        to_emails = list(set(to_emails))
        expires_date = timezone.now() + timezone.timedelta(
            seconds=params['expires_date'])

        # db mutations
        tip = Tip.objects.create(
            emails=to_emails,
            url=params['url'],
            tokenName=params['tokenName'],
            amount=params['amount'],
            comments_priv=params['comments_priv'],
            comments_public=params['comments_public'],
            ip=get_ip(request),
            expires_date=expires_date,
            github_url=params['github_url'],
            from_name=params['from_name'],
            from_email=params['from_email'],
            from_username=from_username,
            username=params['username'],
            network=params['network'],
            tokenAddress=params['tokenAddress'],
            txid=params['txid'],
            from_address=params['from_address'],
        )
        # notifications
        maybe_market_tip_to_github(tip)
        maybe_market_tip_to_slack(tip, 'new_tip')
        maybe_market_tip_to_email(tip, to_emails)
        if not to_emails:
            response['status'] = 'error'
            response[
                'message'] = 'Uh oh! No email addresses for this user were found via Github API.  Youll have to let the tipee know manually about their tip.'

        return JsonResponse(response)

    params = {
        'issueURL':
        request.GET.get('source'),
        'class':
        'send2',
        'title':
        'Send Tip',
        'recommend_gas_price':
        recommend_min_gas_price_to_confirm_in_time(
            confirm_time_minutes_target),
        'from_email':
        primary_from_email,
        'from_handle':
        from_username,
    }

    return TemplateResponse(request, 'yge/send2.html', params)
示例#8
0
def receive_bulk(request, secret):

    coupons = BulkTransferCoupon.objects.filter(secret=secret)
    if not coupons.exists():
        raise Http404

    coupon = coupons.first()

    if coupon.num_uses_remaining <= 0:
        raise PermissionDenied

    kudos_transfer = None
    if request.user.is_authenticated:
        redemptions = BulkTransferRedemption.objects.filter(
            redeemed_by=request.user.profile, coupon=coupon)
        if redemptions.exists():
            kudos_transfer = redemptions.first().kudostransfer

    if request.POST:
        address = Web3.toChecksumAddress(
            request.POST.get('forwarding_address'))
        user = request.user
        profile = user.profile
        save_addr = request.POST.get('save_addr')
        ip_address = get_ip(request)

        # handle form submission
        if save_addr:
            profile.preferred_payout_address = address
            profile.save()

        kudos_contract_address = Web3.toChecksumAddress(
            settings.KUDOS_CONTRACT_MAINNET)
        kudos_owner_address = Web3.toChecksumAddress(
            settings.KUDOS_OWNER_ACCOUNT)
        w3 = get_web3(coupon.token.contract.network)
        contract = w3.eth.contract(
            Web3.toChecksumAddress(kudos_contract_address), abi=kudos_abi())
        tx = contract.functions.clone(
            address, coupon.token.token_id, 1).buildTransaction({
                'nonce':
                get_nonce(coupon.token.contract.network, kudos_owner_address),
                'gas':
                500000,
                'gasPrice':
                int(recommend_min_gas_price_to_confirm_in_time(5) * 10**9),
                'value':
                int(coupon.token.price_finney / 1000.0 * 10**18),
            })

        signed = w3.eth.account.signTransaction(tx, settings.KUDOS_PRIVATE_KEY)
        txid = w3.eth.sendRawTransaction(signed.rawTransaction).hex()

        with transaction.atomic():
            kudos_transfer = KudosTransfer.objects.create(
                emails=[request.user.email],
                # For kudos, `token` is a kudos.models.Token instance.
                kudos_token_cloned_from=coupon.token,
                amount=0,
                comments_public=coupon.comments_to_put_in_kudos_transfer,
                ip=ip_address,
                github_url='',
                from_name=coupon.sender_profile.handle,
                from_email='',
                from_username=coupon.sender_profile.handle,
                username=profile.handle,
                network=coupon.token.contract.network,
                from_address=settings.KUDOS_OWNER_ACCOUNT,
                is_for_bounty_fulfiller=False,
                metadata={'coupon_redemption': True},
                recipient_profile=profile,
                sender_profile=coupon.sender_profile,
                txid=txid,
                receive_txid=txid,
            )

            # save to DB
            BulkTransferRedemption.objects.create(
                coupon=coupon,
                redeemed_by=profile,
                ip_address=ip_address,
                kudostransfer=kudos_transfer,
            )

            coupon.num_uses_remaining -= 1
            coupon.current_uses += 1

    title = f"Redeem AirDropped *{coupon.token.humanized_name}* Kudos"
    desc = f"This Kudos has been AirDropped to you.  About this Kudos: {coupon.token.description}"
    params = {
        'title': title,
        'card_title': title,
        'card_desc': desc,
        'avatar_url': coupon.token.img_url,
        'coupon': coupon,
        'user': request.user,
        'is_authed': request.user.is_authenticated,
        'kudos_transfer': kudos_transfer,
    }
    return TemplateResponse(request, 'transaction/receive_bulk.html', params)
示例#9
0
def account_settings(request):
    """Display and save user's Account settings.

    Returns:
        TemplateResponse: The user's Account settings template response.

    """
    msg = ''
    profile, es, user, is_logged_in = settings_helper_get_auth(request)

    if not user or not profile or not is_logged_in:
        login_redirect = redirect('/login/github?next=' +
                                  request.get_full_path())
        return login_redirect

    if request.POST:
        if 'persona_is_funder' or 'persona_is_hunter' in request.POST.keys():
            profile.persona_is_funder = bool(
                request.POST.get('persona_is_funder', False))
            profile.persona_is_hunter = bool(
                request.POST.get('persona_is_hunter', False))
            profile.save()

        if 'preferred_payout_address' in request.POST.keys():
            eth_address = request.POST.get('preferred_payout_address', '')
            if not is_valid_eth_address(eth_address):
                eth_address = profile.preferred_payout_address
            profile.preferred_payout_address = eth_address
            profile.save()
            msg = _('Updated your Address')
        elif request.POST.get('export', False):
            export_type = request.POST.get('export_type', False)

            response = HttpResponse(content_type='text/csv')
            name = f"gitcoin_{export_type}_{timezone.now().strftime('%Y_%m_%dT%H_00_00')}"
            response[
                'Content-Disposition'] = f'attachment; filename="{name}.csv"'

            writer = csv.writer(response)
            writer.writerow(
                ['id', 'date', 'From', 'To', 'Type', 'Value In USD', 'url'])
            profile = request.user.profile
            earnings = profile.earnings if export_type == 'earnings' else profile.sent_earnings
            earnings = earnings.all().order_by('-created_on')
            for earning in earnings:
                writer.writerow([
                    earning.pk,
                    earning.created_on.strftime("%Y-%m-%dT%H:00:00"),
                    earning.from_profile.handle
                    if earning.from_profile else '*',
                    earning.to_profile.handle if earning.to_profile else '*',
                    earning.source_type.model_class(), earning.value_usd,
                    earning.url
                ])

            return response
        elif request.POST.get('disconnect', False):
            profile.github_access_token = ''
            profile = record_form_submission(request, profile,
                                             'account-disconnect')
            profile.email = ''
            profile.save()
            create_user_action(profile.user, 'account_disconnected', request)
            redirect_url = f'https://www.github.com/settings/connections/applications/{settings.GITHUB_CLIENT_ID}'
            logout(request)
            logout_redirect = redirect(redirect_url)
            logout_redirect[
                'Cache-Control'] = 'max-age=0 no-cache no-store must-revalidate'
            return logout_redirect
        elif request.POST.get('delete', False):

            # remove profile
            profile.hide_profile = True
            profile = record_form_submission(request, profile,
                                             'account-delete')
            profile.email = ''
            profile.save()

            # remove email
            delete_user_from_mailchimp(es.email)

            if es:
                es.delete()
            request.user.delete()
            AccountDeletionRequest.objects.create(handle=profile.handle,
                                                  profile={
                                                      'ip': get_ip(request),
                                                  })
            profile.avatar_baseavatar_related.all().delete()
            try:
                profile.delete()
            except:
                profile.github_access_token = ''
                profile.user = None
                profile.hide_profile = True
                profile.save()
            messages.success(request, _('Your account has been deleted.'))
            logout_redirect = redirect(reverse('logout') + '?next=/')
            return logout_redirect
        else:
            msg = _('Error: did not understand your request')

    context = {
        'is_logged_in': is_logged_in,
        'nav': 'home',
        'active': '/settings/account',
        'title': _('Account Settings'),
        'navs': get_settings_navs(request),
        'es': es,
        'profile': profile,
        'msg': msg,
    }
    return TemplateResponse(request, 'settings/account.html', context)
示例#10
0
def grants(request):
    """Handle grants explorer."""
    limit = request.GET.get('limit', 6)
    page = request.GET.get('page', 1)
    sort = request.GET.get('sort_option', '-created_on')
    network = request.GET.get('network', 'mainnet')
    keyword = request.GET.get('keyword', '')
    state = request.GET.get('state', 'active')
    _grants = None

    if state == 'active':
        _grants = Grant.objects.filter(
            network=network,
            hidden=False).active().keyword(keyword).order_by(sort)
    else:
        _grants = Grant.objects.filter(
            network=network, hidden=False).keyword(keyword).order_by(sort)

    paginator = Paginator(_grants, limit)
    grants = paginator.get_page(page)
    partners = MatchPledge.objects.filter(active=True)

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

    nav_options = [
        {
            'label': 'All',
            'keyword': ''
        },
        {
            'label': 'Security',
            'keyword': 'security'
        },
        {
            'label': 'Scalability',
            'keyword': 'scalability'
        },
        {
            'label': 'UI/UX',
            'keyword': 'UI'
        },
        {
            'label': 'DeFI',
            'keyword': 'defi'
        },
        {
            'label': 'Education',
            'keyword': 'education'
        },
        {
            'label': 'Wallets',
            'keyword': 'wallet'
        },
        {
            'label': 'Community',
            'keyword': 'community'
        },
        {
            'label': 'ETH 2.0',
            'keyword': 'ETH 2.0'
        },
        {
            'label': 'ETH 1.x',
            'keyword': 'ETH 1.x'
        },
    ]

    now = datetime.datetime.now()
    params = {
        'active':
        'grants_landing',
        'title':
        matching_live + str(_('Gitcoin Grants Explorer')),
        'sort':
        sort,
        'network':
        network,
        'keyword':
        keyword,
        'clr_matching_banners_style':
        clr_matching_banners_style,
        'nav_options':
        nav_options,
        'current_partners':
        partners.filter(end_date__gte=now).order_by('-amount'),
        'past_partners':
        partners.filter(end_date__lt=now).order_by('-amount'),
        'card_desc':
        _('Provide sustainable funding for Open Source with Gitcoin Grants'),
        'card_player_override':
        'https://www.youtube.com/embed/eVgEWSPFR2o',
        'card_player_stream_override':
        static('v2/card/grants.mp4'),
        'card_player_thumb_override':
        static('v2/card/grants.png'),
        'grants':
        grants,
        'grants_count':
        _grants.count(),
        'keywords':
        get_keywords(),
        'grant_amount':
        grant_amount,
    }

    # 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

    return TemplateResponse(request, 'grants/index.html', params)
示例#11
0
def preprocess(request):
    """Handle inserting pertinent data into the current context."""

    # make lbcheck super lightweight
    if request.path == '/lbcheck':
        return {}

    from marketing.utils import get_stat
    try:
        num_slack = int(get_stat('slack_users'))
    except Exception:
        num_slack = 0
    if num_slack > 1000:
        num_slack = f'{str(round((num_slack) / 1000, 1))}k'

    user_is_authenticated = request.user.is_authenticated
    profile = request.user.profile if user_is_authenticated and hasattr(
        request.user, 'profile') else None
    email_subs = profile.email_subscriptions if profile else None
    email_key = email_subs.first(
    ).priv if user_is_authenticated and email_subs and email_subs.exists(
    ) else ''
    if user_is_authenticated and profile and profile.pk:
        # what actions to take?
        record_join = not profile.last_visit
        record_visit = not profile.last_visit or profile.last_visit < (
            timezone.now() -
            timezone.timedelta(seconds=RECORD_VISIT_EVERY_N_SECONDS))
        if record_visit:
            ip_address = get_ip(request)
            profile.last_visit = timezone.now()
            try:
                profile.as_dict = json.loads(json.dumps(profile.to_dict()))
                profile.save()
            except Exception as e:
                logger.exception(e)
            metadata = {
                'useragent': request.META['HTTP_USER_AGENT'],
                'referrer': request.META.get('HTTP_REFERER', None),
                'path': request.META.get('PATH_INFO', None),
            }
            UserAction.objects.create(
                user=request.user,
                profile=profile,
                action='Visit',
                location_data=get_location_from_ip(ip_address),
                ip_address=ip_address,
                utm=_get_utm_from_cookie(request),
                metadata=metadata,
            )

        if record_join:
            Activity.objects.create(profile=profile, activity_type='joined')

    # handles marketing callbacks
    if request.GET.get('cb'):
        callback = request.GET.get('cb')
        handle_marketing_callback(callback, request)

    chat_unread_messages = False

    if profile and profile.chat_id:
        try:
            from chat.tasks import get_driver
            chat_driver = get_driver()

            chat_unreads_request = chat_driver.teams.get_team_unreads_for_user(
                profile.chat_id)

            if 'message' not in chat_unreads_request:
                for teams in chat_unreads_request:
                    if teams['msg_count'] > 0 or teams['mention_count'] > 0:
                        chat_unread_messages = True
                        break
        except Exception as e:
            logger.error(str(e))

    context = {
        'STATIC_URL': settings.STATIC_URL,
        'MEDIA_URL': settings.MEDIA_URL,
        'num_slack': num_slack,
        'chat_unread_messages': chat_unread_messages,
        'github_handle':
        request.user.username if user_is_authenticated else False,
        'email': request.user.email if user_is_authenticated else False,
        'name':
        request.user.get_full_name() if user_is_authenticated else False,
        'raven_js_version': settings.RAVEN_JS_VERSION,
        'raven_js_dsn': settings.SENTRY_JS_DSN,
        'release': settings.RELEASE,
        'env': settings.ENV,
        'INFURA_V3_PROJECT_ID': settings.INFURA_V3_PROJECT_ID,
        'email_key': email_key,
        'orgs': profile.organizations if profile else [],
        'profile_id': profile.id if profile else '',
        'hotjar': settings.HOTJAR_CONFIG,
        'ipfs_config': {
            'host': settings.JS_IPFS_HOST,
            'port': settings.IPFS_API_PORT,
            'protocol': settings.IPFS_API_SCHEME,
            'root': settings.IPFS_API_ROOT,
        },
        'access_token': profile.access_token if profile else '',
        'is_staff': request.user.is_staff if user_is_authenticated else False,
        'is_moderator': profile.is_moderator if profile else False,
        'persona_is_funder': profile.persona_is_funder if profile else False,
        'persona_is_hunter': profile.persona_is_hunter if profile else False,
        'profile_url': profile.url if profile else False,
        'quests_live': settings.QUESTS_LIVE,
    }
    context['json_context'] = json.dumps(context)

    if context['github_handle']:
        context['unclaimed_tips'] = Tip.objects.filter(
            expires_date__gte=timezone.now(),
            receive_txid='',
            username__iexact=context['github_handle'],
            web3_type='v3',
        ).send_happy_path()
        context['unclaimed_kudos'] = KudosTransfer.objects.filter(
            receive_txid='',
            username__iexact="@" + context['github_handle'],
            web3_type='v3',
        ).send_happy_path()

        if not settings.DEBUG:
            context['unclaimed_tips'] = context['unclaimed_tips'].filter(
                network='mainnet')
            context['unclaimed_kudos'] = context['unclaimed_kudos'].filter(
                network='mainnet')

    return context
示例#12
0
def grants(request):
    """Handle grants explorer."""
    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', '')
    grant_type = request.GET.get('type', 'tech')
    state = request.GET.get('state', 'active')
    _grants = None

    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])
        sort_by = 'pk'

    if state == 'active':
        _grants = Grant.objects.filter(
            network=network, hidden=False,
            grant_type=grant_type).active().keyword(keyword).order_by(sort)
    else:
        _grants = Grant.objects.filter(
            network=network, hidden=False,
            grant_type=grant_type).keyword(keyword).order_by(sort)

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

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

    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 = grant_stats.first().val / 1000

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

    nav_options = [
        {
            'label': 'All',
            'keyword': ''
        },
        {
            'label': 'Security',
            'keyword': 'security'
        },
        {
            'label': 'Scalability',
            'keyword': 'scalability'
        },
        {
            'label': 'UI/UX',
            'keyword': 'UI'
        },
        {
            'label': 'DeFI',
            'keyword': 'defi'
        },
        {
            'label': 'Education',
            'keyword': 'education'
        },
        {
            'label': 'Wallets',
            'keyword': 'wallet'
        },
        {
            'label': 'Community',
            'keyword': 'community'
        },
        {
            'label': 'ETH 2.0',
            'keyword': 'ETH 2.0'
        },
        {
            'label': 'ETH 1.x',
            'keyword': 'ETH 1.x'
        },
    ]

    grant_types = [{
        'label': 'Tech',
        'keyword': 'tech',
        'count': tech_grants_count
    }, {
        'label': 'Media',
        'keyword': 'media',
        'count': media_grants_count
    }]

    params = {
        'active':
        'grants_landing',
        'title':
        matching_live + str(_('Gitcoin Grants Explorer')),
        'sort':
        sort,
        'network':
        network,
        'keyword':
        keyword,
        'type':
        grant_type,
        'clr_matching_banners_style':
        clr_matching_banners_style,
        'nav_options':
        nav_options,
        'grant_types':
        grant_types,
        'current_partners_fund':
        current_partners_fund,
        'current_partners':
        current_partners,
        'past_partners':
        past_partners,
        'card_desc':
        _('Provide sustainable funding for Open Source with Gitcoin Grants'),
        'card_player_override':
        'https://www.youtube.com/embed/eVgEWSPFR2o',
        'card_player_stream_override':
        static('v2/card/grants.mp4'),
        'card_player_thumb_override':
        static('v2/card/grants.png'),
        'grants':
        grants,
        '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
    }

    # 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

    return TemplateResponse(request, 'grants/index.html', params)
示例#13
0
def send_tip_4(request):
    """Handle the fourth stage of sending a tip (the POST).

    Returns:
        JsonResponse: response with success state.

    """
    response = {
        'status': 'OK',
        'message': _('Tip Sent'),
    }

    is_user_authenticated = request.user.is_authenticated
    from_username = request.user.username if is_user_authenticated else ''

    params = json.loads(request.body)
    txid = params['txid']
    destinationAccount = params['destinationAccount']
    is_direct_to_recipient = params.get('is_direct_to_recipient', False)
    if is_direct_to_recipient:
        tip = Tip.objects.get(
            metadata__direct_address=destinationAccount,
            metadata__creation_time=params['creation_time'],
            metadata__salt=params['salt'],
        )
    else:
        tip = Tip.objects.get(
            metadata__address=destinationAccount,
            metadata__salt=params['salt'],
        )

    is_authenticated_for_this_via_login = (tip.from_username and
                                           tip.from_username == from_username)
    is_authenticated_for_this_via_ip = tip.ip == get_ip(request)
    is_authed = is_authenticated_for_this_via_ip or is_authenticated_for_this_via_login
    if not is_authed:
        response = {
            'status': 'error',
            'message': _('Permission Denied'),
        }
        return JsonResponse(response)

    # db mutations
    tip.txid = txid
    tip.tx_status = 'pending'
    if is_direct_to_recipient:
        tip.receive_txid = txid
        tip.receive_tx_status = 'pending'
        tip.receive_address = destinationAccount
        TipPayout.objects.create(
            txid=txid,
            profile=get_profile(tip.username),
            tip=tip,
        )
    tip.save()

    from townsquare.tasks import calculate_clr_match
    calculate_clr_match.delay()

    # notifications
    maybe_market_tip_to_github(tip)
    maybe_market_tip_to_slack(tip, 'New tip')
    if tip.primary_email:
        maybe_market_tip_to_email(tip, [tip.primary_email])
    record_user_action(tip.from_username, 'send_tip', tip)
    record_tip_activity(tip, tip.from_username,
                        'new_tip' if tip.username else 'new_crowdfund', False,
                        tip.username)

    return JsonResponse(response)
示例#14
0
def preprocess(request):
    """Handle inserting pertinent data into the current context."""

    # make lbcheck super lightweight
    if request.path == '/lbcheck':
        return {}

    from marketing.utils import get_stat
    try:
        num_slack = int(get_stat('slack_users'))
    except Exception:
        num_slack = 0
    if num_slack > 1000:
        num_slack = f'{str(round((num_slack) / 1000, 1))}k'

    user_is_authenticated = request.user.is_authenticated
    profile = request.user.profile if user_is_authenticated and hasattr(request.user, 'profile') else None
    email_subs = profile.email_subscriptions if profile else None
    email_key = email_subs.first().priv if user_is_authenticated and email_subs and email_subs.exists() else ''
    if user_is_authenticated and profile and profile.pk:
        record_visit = not profile.last_visit or profile.last_visit < (
            timezone.now() - timezone.timedelta(seconds=RECORD_VISIT_EVERY_N_SECONDS)
        )
        if record_visit:
            ip_address = get_ip(request)
            profile.last_visit = timezone.now()
            profile.save()
            UserAction.objects.create(
                user=request.user,
                profile=profile,
                action='Visit',
                location_data=get_location_from_ip(ip_address),
                ip_address=ip_address,
                utm=_get_utm_from_cookie(request),
            )
    context = {
        'STATIC_URL': settings.STATIC_URL,
        'MEDIA_URL': settings.MEDIA_URL,
        'num_slack': num_slack,
        'github_handle': request.user.username if user_is_authenticated else False,
        'email': request.user.email if user_is_authenticated else False,
        'name': request.user.get_full_name() if user_is_authenticated else False,
        'sentry_address': settings.SENTRY_ADDRESS,
        'raven_js_version': settings.RAVEN_JS_VERSION,
        'raven_js_dsn': settings.SENTRY_JS_DSN,
        'release': settings.RELEASE,
        'env': settings.ENV,
        'email_key': email_key,
        'profile_id': profile.id if profile else '',
        'hotjar': settings.HOTJAR_CONFIG,
        'ipfs_config': {
            'host': settings.JS_IPFS_HOST,
            'port': settings.IPFS_API_PORT,
            'protocol': settings.IPFS_API_SCHEME,
            'root': settings.IPFS_API_ROOT,
        },
        'access_token': profile.access_token if profile else '',
        'is_staff': request.user.is_staff if user_is_authenticated else False,
        'is_moderator': profile.is_moderator if profile else False,
    }
    context['json_context'] = json.dumps(context)

    if context['github_handle']:
        context['unclaimed_tips'] = Tip.objects.filter(
            expires_date__gte=timezone.now(),
            receive_txid='',
            username__iexact=context['github_handle'],
            web3_type='v3',
        ).send_happy_path()
        context['unclaimed_kudos'] = KudosTransfer.objects.filter(
            receive_txid='', username__iexact="@" + context['github_handle'], web3_type='v3',
        ).send_happy_path()

        if not settings.DEBUG:
            context['unclaimed_tips'] = context['unclaimed_tips'].filter(network='mainnet')
            context['unclaimed_kudos'] = context['unclaimed_kudos'].filter(network='mainnet')

    return context
示例#15
0
文件: views.py 项目: KirkBallou/web
def receive_bulk(request, secret):

    coupons = BulkTransferCoupon.objects.filter(secret=secret)
    if not coupons.exists():
        raise Http404

    coupon = coupons.first()
    _class = request.GET.get('class', '')
    if coupon.num_uses_remaining <= 0:
        messages.info(request, f'Sorry but the coupon for a free kudos has has expired.  Contact the person who sent you the coupon link, or you can still purchase one on this page.')
        return redirect(coupon.token.url)

    kudos_transfer = None
    if request.user.is_authenticated:
        redemptions = BulkTransferRedemption.objects.filter(redeemed_by=request.user.profile, coupon=coupon)
        if redemptions.exists():
            kudos_transfer = redemptions.first().kudostransfer

    error = False
    if request.POST:
        try:
            address = Web3.toChecksumAddress(request.POST.get('forwarding_address'))
        except:
            error = "You must enter a valid Ethereum address (so we know where to send your Kudos). Please try again."
        if request.user.is_anonymous:
            error = "You must login."

        if not error:
            user = request.user
            profile = user.profile
            save_addr = request.POST.get('save_addr')
            ip_address = get_ip(request)

            # handle form submission
            if save_addr:
                profile.preferred_payout_address = address
                profile.save()

            kudos_contract_address = Web3.toChecksumAddress(settings.KUDOS_CONTRACT_MAINNET)
            kudos_owner_address = Web3.toChecksumAddress(settings.KUDOS_OWNER_ACCOUNT)
            w3 = get_web3(coupon.token.contract.network)
            contract = w3.eth.contract(Web3.toChecksumAddress(kudos_contract_address), abi=kudos_abi())
            nonce = w3.eth.getTransactionCount(kudos_owner_address)
            tx = contract.functions.clone(address, coupon.token.token_id, 1).buildTransaction({
                'nonce': nonce,
                'gas': 500000,
                'gasPrice': int(recommend_min_gas_price_to_confirm_in_time(2) * 10**9),
                'value': int(coupon.token.price_finney / 1000.0 * 10**18),
            })

            if not profile.trust_profile and profile.github_created_on > (timezone.now() - timezone.timedelta(days=7)):
                messages.error(request, f'Your github profile is too new.  Cannot receive kudos.')
            else:

                signed = w3.eth.account.signTransaction(tx, settings.KUDOS_PRIVATE_KEY)
                try:
                    txid = w3.eth.sendRawTransaction(signed.rawTransaction).hex()

                    with transaction.atomic():
                        kudos_transfer = KudosTransfer.objects.create(
                            emails=[request.user.email],
                            # For kudos, `token` is a kudos.models.Token instance.
                            kudos_token_cloned_from=coupon.token,
                            amount=coupon.token.price_in_eth,
                            comments_public=coupon.comments_to_put_in_kudos_transfer,
                            ip=ip_address,
                            github_url='',
                            from_name=coupon.sender_profile.handle,
                            from_email='',
                            from_username=coupon.sender_profile.handle,
                            username=profile.handle,
                            network=coupon.token.contract.network,
                            from_address=settings.KUDOS_OWNER_ACCOUNT,
                            is_for_bounty_fulfiller=False,
                            metadata={'coupon_redemption': True, 'nonce': nonce},
                            recipient_profile=profile,
                            sender_profile=coupon.sender_profile,
                            txid=txid,
                            receive_txid=txid,
                            tx_status='pending',
                            receive_tx_status='pending',
                        )

                        # save to DB
                        BulkTransferRedemption.objects.create(
                            coupon=coupon,
                            redeemed_by=profile,
                            ip_address=ip_address,
                            kudostransfer=kudos_transfer,
                            )

                        coupon.num_uses_remaining -= 1
                        coupon.current_uses += 1
                        coupon.save()

                        # send email
                        maybe_market_kudos_to_email(kudos_transfer)
                except:
                    error = "Could not redeem your kudos.  Please try again soon."


    title = f"Redeem {coupon.token.humanized_name} Kudos from @{coupon.sender_profile.handle}"
    desc = f"This Kudos has been AirDropped to you.  About this Kudos: {coupon.token.description}"
    params = {
        'title': title,
        'card_title': title,
        'card_desc': desc,
        'error': error,
        'avatar_url': coupon.token.img_url,
        'coupon': coupon,
        'user': request.user,
        'is_authed': request.user.is_authenticated,
        'kudos_transfer': kudos_transfer,
        'tweet_text': urllib.parse.quote_plus(f"I just got a {coupon.token.humanized_name} Kudos on @gitcoin.  ")
    }
    return TemplateResponse(request, 'transaction/receive_bulk.html', params)
示例#16
0
文件: views.py 项目: gamwe6/web
def whitepaper_access(request, ratelimited=False):

    context = {
        'active': 'whitepaper',
        'title': 'Whitepaper',
        'minihero': 'Whitepaper',
        'suppress_logo': True,
    }
    if not request.POST.get('submit', False):
        return TemplateResponse(request, 'whitepaper_accesscode.html', context)

    if ratelimited:
        context[
            'msg'] = "You're ratelimited. Please contact [email protected]"
        return TemplateResponse(request, 'whitepaper_accesscode.html', context)

    context['accesskey'] = request.POST.get('accesskey')
    context['email'] = request.POST.get('email')
    access_codes = AccessCodes.objects.filter(
        invitecode=request.POST.get('accesskey'))
    valid_access_code = access_codes.exists()
    if not valid_access_code:
        context[
            'msg'] = "Invalid Access Code. Please contact [email protected]"
        return TemplateResponse(request, 'whitepaper_accesscode.html', context)

    ac = access_codes.first()
    if ac.uses >= ac.maxuses:
        context[
            'msg'] = "You have exceeded your maximum number of uses for this access code. Please contact [email protected]"
        return TemplateResponse(request, 'whitepaper_accesscode.html', context)

    valid_email = True
    try:
        validate_email(request.POST.get('email', False))
    except Exception as e:
        valid_email = False

    if not request.POST.get('email', False) or not valid_email:
        context['msg'] = "Invalid Email. Please contact [email protected]"
        return TemplateResponse(request, 'whitepaper_accesscode.html', context)

    ip = get_ip(request)

    wa = WhitepaperAccess.objects.create(
        invitecode=request.POST.get('accesskey', False),
        email=request.POST.get('email', False),
        ip=ip,
    )

    send_mail(settings.CONTACT_EMAIL, settings.CONTACT_EMAIL,
              "New Whitepaper Generated", str(wa))

    # bottom watermark
    packet1 = StringIO.StringIO()
    can = canvas.Canvas(packet1, pagesize=letter)

    grey = Color(22 / 255, 6 / 255, 62 / 255, alpha=0.3)
    can.setFillColor(grey)
    can.setFontSize(8)
    lim = 30
    email__etc = wa.email if len(wa.email) < lim else wa.email[0:lim] + "..."
    msg = "Generated for access code {} by email {} at {} via ip: {}. https://gitcoin.co/whitepaper".format(
        wa.invitecode, email__etc, wa.created_on.strftime("%Y-%m-%d %H:%M"),
        wa.ip)
    charlength = 3.5
    width = len(msg) * charlength
    left = (600 - width) / 2
    can.drawString(left, 7, msg)
    can.save()

    # middle watermark
    packet2 = StringIO.StringIO()
    can = canvas.Canvas(packet2, pagesize=letter)
    grey = Color(22 / 255, 6 / 255, 62 / 255, alpha=0.02)
    can.setFillColor(grey)
    can.setFontSize(100)
    msg = "WP{}".format(str(wa.pk).zfill(5))
    charlength = 55
    width = len(msg) * charlength
    left = (600 - width) / 2
    can.rotate(45)
    can.drawString(320, 50, msg)
    can.save()

    #move to the beginning of the StringIO buffer
    file_name = 'whitepaper.pdf'
    path_to_file = 'assets/other/wp.pdf'
    new_pdf1 = PdfFileReader(packet1)
    new_pdf2 = PdfFileReader(packet2)
    # read your existing PDF
    existing_pdf = PdfFileReader(file(path_to_file, "rb"))
    output = PdfFileWriter()
    # add the "watermark" (which is the new pdf) on the existing page
    try:
        for i in range(0, 50):
            page = existing_pdf.getPage(i)
            page.mergePage(new_pdf1.getPage(0))
            if i != 0:
                page.mergePage(new_pdf2.getPage(0))
            output.addPage(page)
    except Exception as e:
        print(e)
    # finally, write "output" to a real file
    outputfile = "output/whitepaper_{}.pdf".format(wa.pk)
    outputStream = file(outputfile, "wb")
    output.write(outputStream)
    outputStream.close()

    filename = outputfile
    wrapper = FileWrapper(file(filename))
    response = HttpResponse(wrapper, content_type='application/pdf')
    response['Content-Length'] = os.path.getsize(filename)
    return response
示例#17
0
def send_3(request):
    """Handle the third stage of sending a kudos (the POST).

    This function is derived from send_tip_3.
    The request to send the kudos is added to the database, but the transaction
    has not happened yet.  The txid is added in `send_kudos_4`.

    Returns:
        JsonResponse: The response with success state.

    """
    response = {
        'status': 'OK',
        'message': _('Kudos Created'),
    }

    is_user_authenticated = request.user.is_authenticated
    from_username = request.user.username if is_user_authenticated else ''
    primary_from_email = request.user.email if is_user_authenticated else ''
    access_token = request.user.profile.get_access_token() if is_user_authenticated and request.user.profile else ''
    to_emails = []

    params = json.loads(request.body)

    to_username = params.get('username', '').lstrip('@')
    to_emails = get_emails_master(to_username)

    email = params.get('email')
    if email:
        to_emails.append(email)

    # If no primary email in session, try the POST data. If none, fetch from GH.
    primary_from_email = params.get('fromEmail')

    if access_token and not primary_from_email:
        primary_from_email = get_github_primary_email(access_token)

    to_emails = list(set(to_emails))

    # Validate that the token exists on the back-end
    kudos_id = params.get('kudosId')
    if not kudos_id:
        raise Http404

    try:
        kudos_token_cloned_from = Token.objects.get(pk=kudos_id)
    except Token.DoesNotExist:
        raise Http404

    # db mutations
    KudosTransfer.objects.create(
        emails=to_emails,
        # For kudos, `token` is a kudos.models.Token instance.
        kudos_token_cloned_from=kudos_token_cloned_from,
        amount=params['amount'],
        comments_public=params['comments_public'],
        ip=get_ip(request),
        github_url=params['github_url'],
        from_name=params['from_name'],
        from_email=params['from_email'],
        from_username=from_username,
        username=params['username'],
        network=params['network'],
        tokenAddress=params['tokenAddress'],
        from_address=params['from_address'],
        is_for_bounty_fulfiller=params['is_for_bounty_fulfiller'],
        metadata=params['metadata'],
        recipient_profile=get_profile(to_username),
        sender_profile=get_profile(from_username),
    )

    return JsonResponse(response)
示例#18
0
def send_tip_3(request):
    """Handle the third stage of sending a tip (the POST).

    Returns:
        JsonResponse: response with success state.

    """
    response = {
        'status': 'OK',
        'message': _('Tip Created'),
    }

    is_user_authenticated = request.user.is_authenticated
    from_username = request.user.username if is_user_authenticated else ''
    primary_from_email = request.user.email if is_user_authenticated else ''
    access_token = request.user.profile.get_access_token(
    ) if is_user_authenticated and request.user.profile else ''

    params = json.loads(request.body)

    to_username = params['username'].lstrip('@')
    to_emails = get_emails_by_category(to_username)
    primary_email = ''

    if params.get('email'):
        primary_email = params['email']
    elif to_emails.get('primary', None):
        primary_email = to_emails['primary']
    elif to_emails.get('github_profile', None):
        primary_email = to_emails['github_profile']
    else:
        if len(to_emails.get('events', None)):
            primary_email = to_emails['events'][0]
        else:
            print(
                "TODO: no email found.  in the future, we should handle this case better because it's GOING to end up as a support request"
            )
    if primary_email and isinstance(primary_email, list):
        primary_email = primary_email[0]

    # If no primary email in session, try the POST data. If none, fetch from GH.
    if params.get('fromEmail'):
        primary_from_email = params['fromEmail']
    elif access_token and not primary_from_email:
        primary_from_email = get_github_primary_email(access_token)

    expires_date = timezone.now() + timezone.timedelta(
        seconds=params['expires_date'])

    # metadata
    metadata = params['metadata']
    metadata['user_agent'] = request.META.get('HTTP_USER_AGENT', '')

    # db mutations
    tip = Tip.objects.create(
        primary_email=primary_email,
        emails=to_emails,
        tokenName=params['tokenName'],
        amount=params['amount'],
        comments_priv=params['comments_priv'],
        comments_public=params['comments_public'],
        ip=get_ip(request),
        expires_date=expires_date,
        github_url=params['github_url'],
        from_name=params['from_name']
        if params['from_name'] != 'False' else '',
        from_email=params['from_email'],
        from_username=from_username,
        username=params['username'],
        network=params['network'],
        tokenAddress=params['tokenAddress'],
        from_address=params['from_address'],
        is_for_bounty_fulfiller=params['is_for_bounty_fulfiller'],
        metadata=metadata,
        recipient_profile=get_profile(to_username),
        sender_profile=get_profile(from_username),
    )

    is_over_tip_tx_limit = False
    is_over_tip_weekly_limit = False
    max_per_tip = request.user.profile.max_tip_amount_usdt_per_tx if request.user.is_authenticated and request.user.profile else 500
    if tip.value_in_usdt_now:
        is_over_tip_tx_limit = tip.value_in_usdt_now > max_per_tip
        if request.user.is_authenticated and request.user.profile:
            tips_last_week_value = tip.value_in_usdt_now
            tips_last_week = Tip.objects.send_happy_path().filter(
                sender_profile=get_profile(from_username),
                created_on__gt=timezone.now() - timezone.timedelta(days=7))
            for this_tip in tips_last_week:
                if this_tip.value_in_usdt_now:
                    tips_last_week_value += this_tip.value_in_usdt_now
            is_over_tip_weekly_limit = tips_last_week_value > request.user.profile.max_tip_amount_usdt_per_week

    increase_funding_form_title = _('Request a Funding Limit Increasement')
    increase_funding_form = f'<a target="_blank" href="{settings.BASE_URL}'\
                            f'requestincrease">{increase_funding_form_title}</a>'

    if is_over_tip_tx_limit:
        response['status'] = 'error'
        response['message'] = _('This tip is over the per-transaction limit of $') +\
            str(max_per_tip) + '. ' + increase_funding_form
    elif is_over_tip_weekly_limit:
        response['status'] = 'error'
        response['message'] = _('You are over the weekly tip send limit of $') +\
            str(request.user.profile.max_tip_amount_usdt_per_week) +\
            '. ' + increase_funding_form

    return JsonResponse(response)
示例#19
0
文件: views.py 项目: mkosowsk/web
def redeem_coin(request, shortcode):
    if request.body:
        status = 'OK'

        body_unicode = request.body.decode('utf-8')
        body = json.loads(body_unicode)
        address = body['address']

        try:
            coin = CoinRedemption.objects.get(shortcode=shortcode)
            address = Web3.toChecksumAddress(address)

            if hasattr(coin, 'coinredemptionrequest'):
                status = 'error'
                message = 'Bad request'
            else:
                abi = json.loads(
                    '[{"constant":true,"inputs":[],"name":"mintingFinished","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_amount","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"version","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"finishMinting","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"payable":false,"stateMutability":"nonpayable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[],"name":"MintFinished","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]'
                )

                # Instantiate Colorado Coin contract
                contract = w3.eth.contract(coin.contract_address, abi=abi)

                tx = contract.functions.transfer(
                    address, coin.amount * 10**18).buildTransaction({
                        'nonce':
                        w3.eth.getTransactionCount(
                            settings.COLO_ACCOUNT_ADDRESS),
                        'gas':
                        100000,
                        'gasPrice':
                        recommend_min_gas_price_to_confirm_in_time(5) * 10**9
                    })

                signed = w3.eth.account.signTransaction(
                    tx, settings.COLO_ACCOUNT_PRIVATE_KEY)
                transaction_id = w3.eth.sendRawTransaction(
                    signed.rawTransaction).hex()

                CoinRedemptionRequest.objects.create(coin_redemption=coin,
                                                     ip=get_ip(request),
                                                     sent_on=timezone.now(),
                                                     txid=transaction_id,
                                                     txaddress=address)

                message = transaction_id
        except CoinRedemption.DoesNotExist:
            status = 'error'
            message = 'Bad request'
        except Exception as e:
            status = 'error'
            message = str(e)

        # http response
        response = {
            'status': status,
            'message': message,
        }

        return JsonResponse(response)

    try:
        coin = CoinRedemption.objects.get(shortcode=shortcode)

        params = {
            'class': 'redeem',
            'title': 'Coin Redemption',
            'coin_status': 'PENDING'
        }

        try:
            coin_redeem_request = CoinRedemptionRequest.objects.get(
                coin_redemption=coin)
            params['colo_txid'] = coin_redeem_request.txid
        except CoinRedemptionRequest.DoesNotExist:
            params['coin_status'] = 'INITIAL'

        return TemplateResponse(request, 'yge/redeem_coin.html', params)
    except CoinRedemption.DoesNotExist:
        raise Http404
示例#20
0
def email_settings(request, key):
    """Display email settings.

    Args:
        key (str): The private key to lookup email subscriber data.

    TODO:
        * Remove all ES.priv_key lookups and use request.user only.
        * Remove settings_helper_get_auth usage.

    Returns:
        TemplateResponse: The email settings view populated with ES data.

    """
    profile, es, __, __ = settings_helper_get_auth(request, key)
    if not request.user.is_authenticated and (not es and key) or (
            request.user.is_authenticated
            and not hasattr(request.user, 'profile')):
        return redirect('/login/github/?next=' + request.get_full_path())

    # handle 'noinput' case
    email = ''
    level = ''
    msg = ''
    email_types = {}
    from retail.emails import ALL_EMAILS
    for em in ALL_EMAILS:
        email_types[em[0]] = str(em[1])
    email_type = request.GET.get('type')
    if email_type in email_types:
        email = es.email
        if es:
            key = get_or_save_email_subscriber(email, 'settings')
            es.email = email
            unsubscribed_email_type = {}
            unsubscribed_email_type[email_type] = True
            if email_type == 'marketing':
                set_mautic_dnc(profile, es, unsubscribed_email_type)
            es.build_email_preferences(unsubscribed_email_type)
            es = record_form_submission(request, es, 'email')
            ip = get_ip(request)
            if not es.metadata.get('ip', False):
                es.metadata['ip'] = [ip]
            else:
                es.metadata['ip'].append(ip)
            es.save()
        context = {
            'title': _('Email unsubscription successful'),
            'type': email_types[email_type]
        }
        return TemplateResponse(request, 'email_unsubscribed.html', context)
    if request.POST and request.POST.get('submit'):
        email = request.POST.get('email')
        level = request.POST.get('level')
        validation_passed = True
        try:
            email_in_use = User.objects.filter(
                email=email) | User.objects.filter(profile__email=email)
            email_used_marketing = EmailSubscriber.objects.filter(
                email=email).select_related('profile')
            logged_in = request.user.is_authenticated
            email_already_used = (email_in_use or email_used_marketing)
            user = request.user if logged_in else None
            email_used_by_me = (user and (user.email == email
                                          or user.profile.email == email))
            email_changed = es.email != email

            if email_changed and email_already_used and not email_used_by_me:
                raise ValueError(
                    f'{request.user} attempting to use an email which is already in use on the platform'
                )
            validate_email(email)
        except Exception as e:
            print(e)
            validation_passed = False
            msg = str(e)
        if validation_passed:
            if es:
                key = get_or_save_email_subscriber(email, 'settings')
                es.preferences['level'] = level
                es.email = email
                form = dict(request.POST)
                # form was not sending falses, so default them if not there
                for email_tuple in ALL_EMAILS:
                    key = email_tuple[0]
                    if key not in form.keys():
                        form[key] = False

                set_mautic_dnc(profile, es, form)
                es.build_email_preferences(form)
                es = record_form_submission(request, es, 'email')
                ip = get_ip(request)
                es.active = level != 'nothing'
                es.newsletter = level in ['regular', 'lite1']
                if not es.metadata.get('ip', False):
                    es.metadata['ip'] = [ip]
                else:
                    es.metadata['ip'].append(ip)
                es.save()
            msg = _('Updated your preferences.')
    pref_lang = 'en' if not profile else profile.get_profile_preferred_language(
    )
    context = {
        'nav':
        'home',
        'active':
        '/settings/email/',
        'title':
        _('Email Settings'),
        'es':
        es,
        'nav':
        'home',
        'suppression_preferences':
        json.dumps(
            es.preferences.get('suppression_preferences', {}) if es else {}),
        'msg':
        msg,
        'profile':
        request.user.profile if request.user.is_authenticated else None,
        'email_types':
        ALL_EMAILS,
        'navs':
        get_settings_navs(request),
        'preferred_language':
        pref_lang
    }
    return TemplateResponse(request, 'settings/email.html', context)
示例#21
0
    def get_queryset(self):
        """Get the queryset for Bounty.

        Returns:
            QuerySet: The Bounty queryset.

        """
        param_keys = self.request.query_params.keys()
        queryset = Bounty.objects.prefetch_related('fulfillments',
                                                   'interested',
                                                   'interested__profile',
                                                   'activities')
        if 'not_current' not in param_keys:
            queryset = queryset.current()

        queryset = queryset.order_by('-web3_created')

        # filtering
        for key in [
                'raw_data', 'experience_level', 'project_length',
                'bounty_type', 'bounty_owner_address', 'idx_status', 'network',
                'bounty_owner_github_username', 'standard_bounties_id',
                'permission_type', 'project_type'
        ]:
            if key in param_keys:
                # special hack just for looking up bounties posted by a certain person
                request_key = key if key != 'bounty_owner_address' else 'coinbase'
                val = self.request.query_params.get(request_key, '')

                values = val.strip().split(',')
                values = [value for value in values if value and val.strip()]
                if values:
                    _queryset = queryset.none()
                    for value in values:
                        args = {}
                        args[f'{key}__icontains'] = value.strip()
                        _queryset = _queryset | queryset.filter(**args)
                    queryset = _queryset

        # filter by PK
        if 'pk__gt' in param_keys:
            queryset = queryset.filter(
                pk__gt=self.request.query_params.get('pk__gt'))

        # Filter by a list of PKs
        if 'pk__in' in param_keys:
            try:
                list_of_pks = self.request.query_params.get('pk__in').split(
                    ',')
                queryset = queryset.filter(pk__in=list_of_pks)
            except Exception:
                pass

        # filter by standard_bounties_id
        if 'standard_bounties_id__in' in param_keys:
            statuses = self.request.query_params.get(
                'standard_bounties_id__in').split(',')
            queryset = queryset.filter(standard_bounties_id__in=statuses)

        # filter by statuses
        if 'status__in' in param_keys:
            statuses = self.request.query_params.get('status__in').split(',')
            queryset = queryset.filter(idx_status__in=statuses)

        # filter by who is interested
        if 'started' in param_keys:
            queryset = queryset.filter(interested__profile__handle__in=[
                self.request.query_params.get('started')
            ])

        # filter by is open or not
        if 'is_open' in param_keys:
            queryset = queryset.filter(is_open=self.request.query_params.get(
                'is_open', '').lower() == 'true')
            queryset = queryset.filter(expires_date__gt=datetime.now())

        # filter by urls
        if 'github_url' in param_keys:
            urls = self.request.query_params.get('github_url').split(',')
            queryset = queryset.filter(github_url__in=urls)

        # filter by orgs
        if 'org' in param_keys:
            val = self.request.query_params.get('org', '')
            values = val.strip().split(',')
            values = [value for value in values if value and val.strip()]
            if values:
                _queryset = queryset.none()
                for value in values:
                    org = value.strip()
                    _queryset = _queryset | queryset.filter(
                        github_url__icontains=f'https://github.com/{org}')
                queryset = _queryset

        # Retrieve all fullfilled bounties by fulfiller_username
        if 'fulfiller_github_username' in param_keys:
            queryset = queryset.filter(
                fulfillments__fulfiller_github_username__iexact=self.request.
                query_params.get('fulfiller_github_username'))

        # Retrieve all DONE fullfilled bounties by fulfiller_username
        if 'fulfiller_github_username_done' in param_keys:
            queryset = queryset.filter(
                fulfillments__fulfiller_github_username__iexact=self.request.
                query_params.get('fulfiller_github_username'),
                fulfillments__accepted=True,
            )

        # Retrieve all interested bounties by profile handle
        if 'interested_github_username' in param_keys:
            queryset = queryset.filter(
                interested__profile__handle__iexact=self.request.query_params.
                get('interested_github_username'))

        # Retrieve all mod bounties.
        # TODO: Should we restrict this to staff only..? Technically I don't think we're worried about that atm?
        if 'moderation_filter' in param_keys:
            mod_filter = self.request.query_params.get('moderation_filter')
            if mod_filter == 'needs_review':
                queryset = queryset.needs_review()
            elif mod_filter == 'warned':
                queryset = queryset.warned()
            elif mod_filter == 'escalated':
                queryset = queryset.escalated()
            elif mod_filter == 'closed_on_github':
                queryset = queryset.closed()
            elif mod_filter == 'hidden':
                queryset = queryset.hidden()
            elif mod_filter == 'not_started':
                queryset = queryset.not_started()

        # All Misc Api things
        if 'misc' in param_keys:
            if self.request.query_params.get('misc') == 'hiring':
                queryset = queryset.exclude(
                    attached_job_description__isnull=True).exclude(
                        attached_job_description='')

        if 'keyword' in param_keys:
            queryset = queryset.keyword(
                self.request.query_params.get('keyword'))

        if 'is_featured' in param_keys:
            queryset = queryset.filter(
                is_featured=self.request.query_params.get('is_featured'),
                is_open=True,
            )

        # order
        order_by = self.request.query_params.get('order_by')
        if order_by and order_by != 'null':
            queryset = queryset.order_by(order_by)

        queryset = queryset.distinct()

        # offset / limit
        if 'is_featured' not in param_keys:
            limit = int(self.request.query_params.get('limit', 5))
            max_bounties = 100
            if limit > max_bounties:
                limit = max_bounties
            offset = self.request.query_params.get('offset', 0)
            if limit:
                start = int(offset)
                end = start + int(limit)
                queryset = queryset[start:end]

        data = dict(self.request.query_params)
        data.pop('is_featured', None)

        # save search history, but only not is_featured
        if 'is_featured' not in param_keys:
            if self.request.user and self.request.user.is_authenticated:
                data['nonce'] = int(time.time() / 1000)
                SearchHistory.objects.update_or_create(user=self.request.user,
                                                       data=data,
                                                       ip_address=get_ip(
                                                           self.request))

        return queryset
示例#22
0
def account_settings(request):
    """Display and save user's Account settings.

    Returns:
        TemplateResponse: The user's Account settings template response.

    """
    msg = ''
    profile, es, user, is_logged_in = settings_helper_get_auth(request)

    if not user or not profile or not is_logged_in:
        login_redirect = redirect('/login/github/?next=' +
                                  request.get_full_path())
        return login_redirect

    if request.POST:
        if 'persona_is_funder' or 'persona_is_hunter' in request.POST.keys():
            profile.persona_is_funder = bool(
                request.POST.get('persona_is_funder', False))
            profile.persona_is_hunter = bool(
                request.POST.get('persona_is_hunter', False))
            profile.save()

        if 'preferred_payout_address' in request.POST.keys():
            eth_address = request.POST.get('preferred_payout_address', '')
            if not is_valid_eth_address(eth_address):
                eth_address = profile.preferred_payout_address
            profile.preferred_payout_address = eth_address
            profile.save()
            msg = _('Updated your Address')
        elif request.POST.get('export', False):
            export_type = request.POST.get('export_type', False)

            profile = request.user.profile
            earnings = profile.earnings if export_type == 'earnings' else profile.sent_earnings
            earnings = earnings.filter(
                network='mainnet').order_by('-created_on')
            return export_earnings_csv(earnings, export_type)
        elif request.POST.get('disconnect', False):
            profile.github_access_token = ''
            profile = record_form_submission(request, profile,
                                             'account-disconnect')
            profile.email = ''
            profile.save()
            create_user_action(profile.user, 'account_disconnected', request)
            redirect_url = f'https://www.github.com/settings/connections/applications/{settings.GITHUB_CLIENT_ID}'
            logout(request)
            logout_redirect = redirect(redirect_url)
            logout_redirect[
                'Cache-Control'] = 'max-age=0 no-cache no-store must-revalidate'
            return logout_redirect
        elif request.POST.get('delete', False):

            # remove profile
            profile.hide_profile = True
            profile = record_form_submission(request, profile,
                                             'account-delete')
            profile.email = ''
            profile.save()

            # remove email
            mautic_proxy_backend('POST',
                                 f'contacts/{profile.mautic_id}/delete')

            if es:
                es.delete()
            request.user.delete()
            AccountDeletionRequest.objects.create(
                handle=profile.handle.lower(),
                profile={
                    'ip': get_ip(request),
                })
            profile.avatar_baseavatar_related.all().delete()
            try:
                profile.delete()
            except:
                profile.github_access_token = ''
                profile.user = None
                profile.hide_profile = True
                profile.save()
            messages.success(request, _('Your account has been deleted.'))
            logout_redirect = redirect(reverse('logout') + '?next=/')
            return logout_redirect
        else:
            msg = _('Error: did not understand your request')

    context = {
        'is_logged_in': is_logged_in,
        'nav': 'home',
        'active': '/settings/account',
        'title': _('Account Settings'),
        'navs': get_settings_navs(request),
        'es': es,
        'profile': profile,
        'msg': msg,
    }
    return TemplateResponse(request, 'settings/account.html', context)
示例#23
0
def preprocess(request):
    """Handle inserting pertinent data into the current context."""

    # make lbcheck super lightweight
    if request.path == '/lbcheck':
        return {}

    chat_url = get_chat_url(front_end=True)
    chat_access_token = ''
    chat_id = ''

    user_is_authenticated = request.user.is_authenticated
    profile = request.user.profile if user_is_authenticated and hasattr(
        request.user, 'profile') else None
    if user_is_authenticated and profile and profile.pk:
        # what actions to take?
        record_join = not profile.last_visit
        record_visit = not profile.last_visit or profile.last_visit < (
            timezone.now() -
            timezone.timedelta(seconds=RECORD_VISIT_EVERY_N_SECONDS))
        if record_visit:
            try:
                profile.last_visit = timezone.now()
                profile.save()
            except Exception as e:
                logger.exception(e)
            try:
                from dashboard.tasks import profile_dict
                profile_dict.delay(profile.pk)
            except Exception as e:
                logger.exception(e)
            metadata = {
                'useragent': request.META['HTTP_USER_AGENT'],
                'referrer': request.META.get('HTTP_REFERER', None),
                'path': request.META.get('PATH_INFO', None),
            }
            ip_address = get_ip(request)
            UserAction.objects.create(
                user=request.user,
                profile=profile,
                action='Visit',
                location_data=get_location_from_ip(ip_address),
                ip_address=ip_address,
                utm=_get_utm_from_cookie(request),
                metadata=metadata,
            )

        if record_join:
            Activity.objects.create(profile=profile, activity_type='joined')

        chat_access_token = profile.gitcoin_chat_access_token
        chat_id = profile.chat_id
    # handles marketing callbacks
    if request.GET.get('cb'):
        callback = request.GET.get('cb')
        handle_marketing_callback(callback, request)

    header_msg, footer_msg, nav_salt = get_sitewide_announcements()

    context = {
        'STATIC_URL':
        settings.STATIC_URL,
        'MEDIA_URL':
        settings.MEDIA_URL,
        'chat_url':
        chat_url,
        'chat_id':
        chat_id,
        'chat_access_token':
        chat_access_token,
        'github_handle':
        request.user.username.lower() if user_is_authenticated else False,
        'email':
        request.user.email if user_is_authenticated else False,
        'name':
        request.user.get_full_name() if user_is_authenticated else False,
        'last_chat_status':
        request.user.profile.last_chat_status if
        (hasattr(request.user, 'profile')
         and user_is_authenticated) else False,
        'raven_js_version':
        settings.RAVEN_JS_VERSION,
        'raven_js_dsn':
        settings.SENTRY_JS_DSN,
        'release':
        settings.RELEASE,
        'env':
        settings.ENV,
        'header_msg':
        header_msg,
        'nav_salt':
        nav_salt,
        'footer_msg':
        footer_msg,
        'INFURA_V3_PROJECT_ID':
        settings.INFURA_V3_PROJECT_ID,
        'giphy_key':
        settings.GIPHY_KEY,
        'youtube_key':
        settings.YOUTUBE_API_KEY,
        'orgs':
        profile.organizations if profile else [],
        'profile_id':
        profile.id if profile else '',
        'hotjar':
        settings.HOTJAR_CONFIG,
        'ipfs_config': {
            'host': settings.JS_IPFS_HOST,
            'port': settings.IPFS_API_PORT,
            'protocol': settings.IPFS_API_SCHEME,
            'root': settings.IPFS_API_ROOT,
        },
        'chat_persistence_frequency':
        90 * 1000,
        'access_token':
        profile.access_token if profile else '',
        'is_staff':
        request.user.is_staff if user_is_authenticated else False,
        'is_moderator':
        profile.is_moderator if profile else False,
        'is_alpha_tester':
        profile.is_alpha_tester if profile else False,
        'persona_is_funder':
        profile.persona_is_funder if profile else False,
        'persona_is_hunter':
        profile.persona_is_hunter if profile else False,
        'profile_url':
        profile.url if profile else False,
        'quests_live':
        settings.QUESTS_LIVE,
    }
    context['json_context'] = json.dumps(context)
    context['last_posts'] = cache.get_or_set('last_posts', fetchPost, 5000)

    if context['github_handle']:
        context['unclaimed_tips'] = Tip.objects.filter(
            receive_txid='',
            username__iexact=context['github_handle'],
            web3_type='v3',
        ).send_happy_path().cache(timeout=60)
        context['unclaimed_kudos'] = KudosTransfer.objects.filter(
            receive_txid='',
            username__iexact="@" + context['github_handle'],
            web3_type='v3',
        ).send_happy_path().cache(timeout=60)

        if not settings.DEBUG:
            context['unclaimed_tips'] = context['unclaimed_tips'].filter(
                network='mainnet').cache(timeout=60)
            context['unclaimed_kudos'] = context['unclaimed_kudos'].filter(
                network='mainnet').cache(timeout=60)

    return context
示例#24
0
def job_settings(request):
    """Display and save user's Account settings.

    Returns:
        TemplateResponse: The user's Account settings template response.

    """
    msg = ''
    profile, es, user, is_logged_in = settings_helper_get_auth(request)

    if not user or not profile or not is_logged_in:
        login_redirect = redirect('/login/github/?next=' +
                                  request.get_full_path())
        return login_redirect

    if request.POST:

        if 'preferred_payout_address' in request.POST.keys():
            eth_address = request.POST.get('preferred_payout_address', '')
            if not is_valid_eth_address(eth_address):
                eth_address = profile.preferred_payout_address
            profile.preferred_payout_address = eth_address
            profile.save()
            msg = _('Updated your Address')
        elif request.POST.get('disconnect', False):
            profile.github_access_token = ''
            profile = record_form_submission(request, profile,
                                             'account-disconnect')
            profile.email = ''
            profile.save()
            create_user_action(profile.user, 'account_disconnected', request)
            messages.success(
                request, _('Your account has been disconnected from Github'))
            logout_redirect = redirect(reverse('logout') + '?next=/')
            return logout_redirect
        elif request.POST.get('delete', False):

            # remove profile
            profile.hide_profile = True
            profile = record_form_submission(request, profile,
                                             'account-delete')
            profile.email = ''
            profile.save()

            # remove email
            mautic_proxy_backend('POST',
                                 f'contacts/{profile.mautic_id}/delete')

            if es:
                es.delete()
            request.user.delete()
            AccountDeletionRequest.objects.create(
                handle=profile.handle.lower(),
                profile={
                    'ip': get_ip(request),
                })
            profile.delete()
            messages.success(request, _('Your account has been deleted.'))
            logout_redirect = redirect(reverse('logout') + '?next=/')
            return logout_redirect
        else:
            msg = _('Error: did not understand your request')

    context = {
        'is_logged_in': is_logged_in,
        'nav': 'home',
        'active': '/settings/job',
        'title': _('Job Settings'),
        'navs': get_settings_navs(request),
        'es': es,
        'profile': profile,
        'msg': msg,
    }
    return TemplateResponse(request, 'settings/job.html', context)
示例#25
0
def email_settings(request, key):
    """Display email settings.

    Args:
        key (str): The private key to lookup email subscriber data.

    TODO:
        * Remove all ES.priv_key lookups and use request.user only.
        * Remove settings_helper_get_auth usage.

    Returns:
        TemplateResponse: The email settings view populated with ES data.

    """
    profile, es, user, is_logged_in = settings_helper_get_auth(request, key)
    if not request.user.is_authenticated and (not es and key) or (
            request.user.is_authenticated
            and not hasattr(request.user, 'profile')):
        return redirect('/login/github?next=' + request.get_full_path())

    # handle 'noinput' case
    email = ''
    level = ''
    msg = ''
    if request.POST and request.POST.get('submit'):
        email = request.POST.get('email')
        level = request.POST.get('level')
        preferred_language = request.POST.get('preferred_language')
        validation_passed = True
        try:
            validate_email(email)
        except Exception as e:
            print(e)
            validation_passed = False
            msg = _('Invalid Email')
        if preferred_language:
            if preferred_language not in [i[0] for i in settings.LANGUAGES]:
                msg = _('Unknown language')
                validation_passed = False
        if validation_passed:
            if profile:
                profile.pref_lang_code = preferred_language
                profile.save()
                request.session[LANGUAGE_SESSION_KEY] = preferred_language
                translation.activate(preferred_language)
            if es:
                key = get_or_save_email_subscriber(email, 'settings')
                es.preferences['level'] = level
                es.email = email
                form = dict(request.POST)
                # form was not sending falses, so default them if not there
                for email_tuple in ALL_EMAILS:
                    key = email_tuple[0]
                    if key not in form.keys():
                        form[key] = False
                es.build_email_preferences(form)
                es = record_form_submission(request, es, 'email')
                ip = get_ip(request)
                es.active = level != 'nothing'
                es.newsletter = level in ['regular', 'lite1']
                if not es.metadata.get('ip', False):
                    es.metadata['ip'] = [ip]
                else:
                    es.metadata['ip'].append(ip)
                es.save()
            msg = _('Updated your preferences.')
    pref_lang = 'en' if not profile else profile.get_profile_preferred_language(
    )
    context = {
        'nav':
        'internal',
        'active':
        '/settings/email',
        'title':
        _('Email Settings'),
        'es':
        es,
        'suppression_preferences':
        json.dumps(
            es.preferences.get('suppression_preferences', {}) if es else {}),
        'msg':
        msg,
        'email_types':
        ALL_EMAILS,
        'navs':
        get_settings_navs(request),
        'preferred_language':
        pref_lang
    }
    return TemplateResponse(request, 'settings/email.html', context)
示例#26
0
文件: views.py 项目: speizerj/web
def email_settings(request, key):
    email = ''
    level = ''
    msg = ''
    es = EmailSubscriber.objects.filter(priv=key)
    if es.exists():
        email = es.first().email
        level = es.first().preferences.get('level', False)
    es = es.first()
    if request.POST.get('email', False):
        level = request.POST.get('level')
        comments = request.POST.get('comments')[:255]
        email = request.POST.get('email')
        github = request.POST.get('github')
        print(es.github)
        keywords = request.POST.get('keywords').split(',')
        validation_passed = True
        try:
            validate_email(email)
        except Exception as e:
            print(e)
            validation_passed = False
            msg = 'Invalid Email'

        if level not in ['lite', 'regular', 'nothing']:
            validation_passed = False
            msg = 'Invalid Level'
        if validation_passed:
            key = get_or_save_email_subscriber(email, 'settings')
            es = EmailSubscriber.objects.get(priv=key)
            es.preferences['level'] = level
            es.metadata['comments'] = comments
            es.github = github
            es.keywords = keywords
            ip = get_ip(request)
            es.active = level != 'nothing'
            es.newsletter = level in ['regular', 'lite1']
            if not es.metadata.get('ip', False):
                es.metadata['ip'] = [ip]
            else:
                es.metadata['ip'].append(ip)

            es.save()
            msg = "Updated your preferences.  "
    context = {
        'active':
        'email_settings',
        'title':
        'Email Settings',
        'es':
        es,
        'keywords':
        ",".join(es.keywords),
        'msg':
        msg,
        'autocomplete_keywords':
        json.dumps([
            str(key)
            for key in Keyword.objects.all().values_list('keyword', flat=True)
        ]),
    }
    return TemplateResponse(request, 'email_settings.html', context)
示例#27
0
def newkudos(request):
    context = {
        'active': 'newkudos',
        'msg': None,
        'nav': 'kudos',
        'title': "Mint new Kudos",
        'avatar_url': request.build_absolute_uri(static('v2/images/twitter_cards/tw_cards-06.png')),
    }

    if not request.user.is_authenticated:
        login_redirect = redirect('/login/github/?next=' + request.get_full_path())
        return login_redirect

    if request.POST:
        required_fields = ['name', 'description', 'priceFinney', 'artist', 'platform', 'numClonesAllowed', 'tags', 'to_address']
        validation_passed = True
        for key in required_fields:
            if not request.POST.get(key):
                context['msg'] = str(_('You must provide the following fields: ')) + key
                validation_passed = False
        if validation_passed:
            #upload to s3
            img = request.FILES.get('photo')
            session = boto3.Session(
                aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
                aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
            )

            s3 = session.resource('s3')
            key = f'media/uploads/{uuid.uuid4()}_{img.name}'
            response = s3.Bucket(settings.MEDIA_BUCKET).put_object(Key=key, Body=img, ACL='public-read', ContentType='image/svg+xml')
            artwork_url = f'https://{settings.MEDIA_BUCKET}.s3-us-west-2.amazonaws.com/{key}'

            # save / send email
            obj = TokenRequest.objects.create(
                profile=request.user.profile,
                name=request.POST['name'],
                description=request.POST['description'],
                priceFinney=request.POST['priceFinney'],
                artist=request.POST['artist'],
                bounty_url=request.POST['bounty_url'],
                platform=request.POST['platform'],
                numClonesAllowed=request.POST['numClonesAllowed'],
                tags=request.POST['tags'].split(","),
                to_address=request.POST['to_address'],
                artwork_url=artwork_url,
                network='xdai',
                approved=False,
                metadata={
                    'ip': get_ip(request),
                    'email': request.POST.get('email'),
                    'pay_gas': request.POST.get('pay_gas', 0),
                    }
                )
            new_kudos_request(obj)

            context['msg'] = str(_('Your Kudos has been submitted and will be listed within 2 business days if it is accepted.'))

            if request.user.is_staff:
                if request.POST.get('mint_and_sync'):
                    from kudos.tasks import mint_token_request
                    mint_token_request.delay(obj.id)
                    context['msg'] = str(_('Kudos mint/sync submitted'))

    return TemplateResponse(request, 'newkudos.html', context)
示例#28
0
文件: views.py 项目: yash-mathne/web
def receive_bulk_ethdenver(request, secret):

    coupons = BulkTransferCoupon.objects.filter(secret=secret)
    if not coupons.exists():
        raise Http404

    coupon = coupons.first()

    kudos_transfer = ""
    if coupon.num_uses_remaining <= 0:
        messages.info(
            request,
            f'Sorry but this kudos redeem link has expired! Please contact the person who sent you the coupon link, or contact your nearest Gitcoin representative.'
        )
        return redirect(coupon.token.url)

    error = False
    if request.POST:
        try:
            address = Web3.toChecksumAddress(
                request.POST.get('forwarding_address'))
        except:
            error = "You must enter a valid Ethereum address (so we know where to send your Kudos). Please try again."
        if not error:
            address = Web3.toChecksumAddress(
                request.POST.get('forwarding_address'))
            already_claimed = KudosTransfer.objects.filter(
                receive_address=address, kudos_token_cloned_from=coupon.token)
            if already_claimed.count() > 0:
                messages.info(
                    request,
                    f'You already redeemed this kudos! If you think this wrong contact the ETHDenver Team!'
                )
                return redirect(coupon.token.url)
            ip_address = get_ip(request)

            kudos_contract_address = Web3.toChecksumAddress(
                settings.KUDOS_CONTRACT_MAINNET)
            kudos_owner_address = Web3.toChecksumAddress(
                settings.KUDOS_OWNER_ACCOUNT)
            w3 = get_web3(coupon.token.contract.network)
            nonce = w3.eth.getTransactionCount(kudos_owner_address)
            contract = w3.eth.contract(
                Web3.toChecksumAddress(kudos_contract_address),
                abi=kudos_abi())
            tx = contract.functions.clone(
                address, coupon.token.token_id, 1).buildTransaction({
                    'nonce':
                    nonce,
                    'gas':
                    500000,
                    'gasPrice':
                    int(recommend_min_gas_price_to_confirm_in_time(1) * 10**9),
                    'value':
                    int(coupon.token.price_finney / 1000.0 * 10**18),
                })

            try:
                signed = w3.eth.account.signTransaction(
                    tx, settings.KUDOS_PRIVATE_KEY)
                txid = w3.eth.sendRawTransaction(signed.rawTransaction).hex()

                with transaction.atomic():
                    kudos_transfer = KudosTransfer.objects.create(
                        emails=["*****@*****.**"],
                        # For kudos, `token` is a kudos.models.Token instance.
                        kudos_token_cloned_from=coupon.token,
                        amount=coupon.token.price_in_eth,
                        comments_public=coupon.
                        comments_to_put_in_kudos_transfer,
                        ip=ip_address,
                        github_url='',
                        from_name=coupon.sender_profile.handle,
                        from_email='',
                        from_username=coupon.sender_profile.handle,
                        network=coupon.token.contract.network,
                        from_address=settings.KUDOS_OWNER_ACCOUNT,
                        receive_address=address,
                        is_for_bounty_fulfiller=False,
                        metadata={'coupon_redemption': True},
                        sender_profile=coupon.sender_profile,
                        txid=txid,
                        receive_txid=txid,
                        tx_status='pending',
                        receive_tx_status='pending',
                    )

                    coupon.num_uses_remaining -= 1
                    coupon.current_uses += 1
                    coupon.save()
            except:
                error = "Could not redeem your kudos.  Please try again soon."

    title = f"Redeem ETHDenver event kudos: *{coupon.token.humanized_name}*"
    desc = f"Thank you for joining the event! About this Kudos: {coupon.token.description}"
    params = {
        'title': title,
        'card_title': title,
        'card_desc': desc,
        'error': error,
        'avatar_url': coupon.token.img_url,
        'coupon': coupon,
        'user': request.user,
        'is_authed': request.user.is_authenticated,
        'kudos_transfer': kudos_transfer,
    }
    return TemplateResponse(request, 'ethdenver2019/receive_bulk.html', params)
示例#29
0
def send_3(request):
    """Handle the third stage of sending a kudos (the POST).

    This function is derived from send_tip_3.
    The request to send the kudos is added to the database, but the transaction
    has not happened yet.  The txid is added in `send_kudos_4`.

    Returns:
        JsonResponse: The response with success state.

    """
    response = {
        'status': 'OK',
        'message': _('Kudos Created'),
    }

    is_user_authenticated = request.user.is_authenticated
    from_username = request.user.username if is_user_authenticated else ''
    primary_from_email = request.user.email if is_user_authenticated else ''
    access_token = request.user.profile.get_access_token() if is_user_authenticated and request.user.profile else ''

    params = json.loads(request.body)

    to_username = params.get('username', '').lstrip('@')
    to_emails = get_emails_by_category(to_username)
    primary_email = ''

    if params.get('email'):
        primary_email = params['email']
    elif to_emails.get('primary', None):
        primary_email = to_emails['primary']
    elif to_emails.get('github_profile', None):
        primary_email = to_emails['github_profile']
    else:
        if len(to_emails.get('events', None)):
            primary_email = to_emails['events'][0]
        else:
            print("TODO: no email found.  in the future, we should handle this case better because it's GOING to end up as a support request")
    if primary_email and isinstance(primary_email, list):
        primary_email = primary_email[0]

    # If no primary email in session, try the POST data. If none, fetch from GH.
    primary_from_email = params.get('fromEmail')

    if access_token and not primary_from_email:
        primary_from_email = get_github_primary_email(access_token)

    # Validate that the token exists on the back-end
    kudos_id = params.get('kudosId')
    if not kudos_id:
        raise Http404

    try:
        kudos_token_cloned_from = Token.objects.get(pk=kudos_id)
    except Token.DoesNotExist:
        raise Http404

    # db mutations
    kt = KudosTransfer.objects.create(
        primary_email=primary_email,
        emails=to_emails,
        # For kudos, `token` is a kudos.models.Token instance.
        kudos_token_cloned_from=kudos_token_cloned_from,
        amount=params['amount'],
        comments_public=params['comments_public'],
        ip=get_ip(request),
        github_url=params['github_url'],
        from_name=params['from_name'],
        from_email=params['from_email'],
        from_username=from_username,
        username=params['username'],
        network=params['network'],
        tokenAddress=params.get('tokenAddress', ''),
        from_address=params['from_address'],
        is_for_bounty_fulfiller=params['is_for_bounty_fulfiller'],
        metadata=params['metadata'],
        recipient_profile=get_profile(to_username),
        sender_profile=get_profile(from_username),
    )

    if params.get('send_type') == 'airdrop' and is_user_authenticated:
        num_redemptions = params['num_redemptions']
        if not params.get('pk'):
            raise Exception('You must provide a pk')

        btc = BulkTransferCoupon.objects.create(
            token=kudos_token_cloned_from,
            num_uses_remaining=num_redemptions,
            num_uses_total=num_redemptions,
            current_uses=0,
            secret=random.randint(10**19, 10**20),
            comments_to_put_in_kudos_transfer=params['comments_public'],
            sender_address=params['metadata']['address'],
            sender_pk=params.get('pk'),
            sender_profile=get_profile(from_username),
            )
        response['url'] = btc.url

    return JsonResponse(response)
示例#30
0
def preprocess(request):
    """Handle inserting pertinent data into the current context."""

    # make lbcheck super lightweight

    if request.path == '/lbcheck':
        return {}

    ptoken = None

    search_url = ''
    user_is_authenticated = request.user.is_authenticated
    profile = request.user.profile if user_is_authenticated and hasattr(
        request.user, 'profile') else None
    if user_is_authenticated and profile and profile.pk:
        # what actions to take?
        record_join = not profile.last_visit
        record_visit = not profile.last_visit or profile.last_visit < (
            timezone.now() -
            timezone.timedelta(seconds=RECORD_VISIT_EVERY_N_SECONDS))
        if record_visit:
            try:
                profile.last_visit = timezone.now()
                profile.save()
            except Exception as e:
                logger.exception(e)
            try:
                from dashboard.tasks import profile_dict
                profile_dict.delay(profile.pk)
            except Exception as e:
                logger.exception(e)
            metadata = {
                'visitorId': request.COOKIES.get("visitorId", None),
                'useragent': request.META['HTTP_USER_AGENT'],
                'referrer': request.META.get('HTTP_REFERER', None),
                'path': request.META.get('PATH_INFO', None),
                'session_key': request.session._session_key,
            }
            ip_address = get_ip(request)
            UserAction.objects.create(
                user=request.user,
                profile=profile,
                action='Visit',
                location_data=get_location_from_ip(ip_address),
                ip_address=ip_address,
                utm=_get_utm_from_cookie(request),
                metadata=metadata,
            )

        if record_join:
            Activity.objects.create(profile=profile, activity_type='joined')

        ptoken = PersonalToken.objects.filter(
            token_owner_profile=profile).first()

    # Check if user's location supports pTokens
    try:
        current_location = profile.locations[-1]
        is_location_blocked_for_ptokens = current_location['country_code'] == settings.PTOKEN_BLOCKED_REGION['country_code'] \
            and current_location['region'] == settings.PTOKEN_BLOCKED_REGION['region']
    except:
        # If user is not logged in
        is_location_blocked_for_ptokens = False

    # handles marketing callbacks
    if request.GET.get('cb'):
        callback = request.GET.get('cb')
        handle_marketing_callback(callback, request)

    header_msg, footer_msg, nav_salt = get_sitewide_announcements()

    try:
        onboard_tasks = JSONStore.objects.get(key='onboard_tasks').data
    except JSONStore.DoesNotExist:
        onboard_tasks = []

    # town square wall post max length
    max_length_offset = abs(
        ((request.user.profile.created_on if hasattr(request.user, 'profile')
          and request.user.is_authenticated else timezone.now()) -
         timezone.now()).days)
    max_length = 600 + max_length_offset

    context = {
        'STATIC_URL':
        settings.STATIC_URL,
        'MEDIA_URL':
        settings.MEDIA_URL,
        'max_length':
        max_length,
        'max_length_offset':
        max_length_offset,
        'search_url':
        f'{settings.BASE_URL}user_lookup',
        'base_url':
        settings.BASE_URL,
        'github_handle':
        request.user.username.lower() if user_is_authenticated else False,
        'email':
        request.user.email if user_is_authenticated else False,
        'name':
        request.user.get_full_name() if user_is_authenticated else False,
        'raven_js_version':
        settings.RAVEN_JS_VERSION,
        'raven_js_dsn':
        settings.SENTRY_JS_DSN,
        'release':
        settings.RELEASE,
        'env':
        settings.ENV,
        'header_msg':
        header_msg,
        'nav_salt':
        nav_salt,
        'footer_msg':
        footer_msg,
        'INFURA_V3_PROJECT_ID':
        settings.INFURA_V3_PROJECT_ID,
        'giphy_key':
        settings.GIPHY_KEY,
        'youtube_key':
        settings.YOUTUBE_API_KEY,
        'fortmatic_live_key':
        settings.FORTMATIC_LIVE_KEY,
        'fortmatic_test_key':
        settings.FORTMATIC_TEST_KEY,
        'orgs':
        profile.organizations if profile else [],
        'profile_id':
        profile.id if profile else '',
        'is_pro':
        profile.is_pro if profile else False,
        'hotjar':
        settings.HOTJAR_CONFIG,
        'ipfs_config': {
            'host': settings.JS_IPFS_HOST,
            'port': settings.IPFS_API_PORT,
            'protocol': settings.IPFS_API_SCHEME,
            'root': settings.IPFS_API_ROOT,
        },
        'access_token':
        profile.access_token if profile else '',
        'is_staff':
        request.user.is_staff if user_is_authenticated else False,
        'is_moderator':
        profile.is_moderator if profile else False,
        'is_alpha_tester':
        profile.is_alpha_tester if profile else False,
        'user_groups':
        list(profile.user_groups) if profile else False,
        'persona_is_funder':
        profile.persona_is_funder if profile else False,
        'persona_is_hunter':
        profile.persona_is_hunter if profile else False,
        'pref_do_not_track':
        profile.pref_do_not_track if profile else False,
        'profile_url':
        profile.url if profile else False,
        'quests_live':
        settings.QUESTS_LIVE,
        'onboard_tasks':
        onboard_tasks,
        'ptoken_abi':
        settings.PTOKEN_ABI,
        'ptoken_factory_address':
        settings.PTOKEN_FACTORY_ADDRESS,
        'ptoken_factory_abi':
        settings.PTOKEN_FACTORY_ABI,
        'ptoken_address':
        ptoken.token_address if ptoken else '',
        'ptoken_id':
        ptoken.id if ptoken else None,
        'is_location_blocked_for_ptokens':
        is_location_blocked_for_ptokens,
        'match_payouts_abi':
        settings.MATCH_PAYOUTS_ABI,
        'match_payouts_address':
        settings.MATCH_PAYOUTS_ADDRESS,
        'mautic_id':
        profile.mautic_id if profile else None,
    }
    context['json_context'] = json.dumps(context)
    context['last_posts'] = cache.get_or_set('last_posts', fetchPost, 5000)

    if context['github_handle']:
        context['unclaimed_tips'] = Tip.objects.filter(
            receive_txid='',
            username__iexact=context['github_handle'],
            web3_type='v3',
        ).send_happy_path().cache(timeout=60)
        context['unclaimed_kudos'] = KudosTransfer.objects.filter(
            receive_txid='',
            username__iexact="@" + context['github_handle'],
            web3_type='v3',
        ).send_happy_path().cache(timeout=60)

        if not settings.DEBUG:
            context['unclaimed_tips'] = context['unclaimed_tips'].filter(
                network='mainnet').cache(timeout=60)
            context['unclaimed_kudos'] = context['unclaimed_kudos'].filter(
                network='mainnet').cache(timeout=60)

    return context