Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/stable'
Browse files Browse the repository at this point in the history
  • Loading branch information
gdixon committed Sep 27, 2021
2 parents 8d405ef + 91a8284 commit 0717294
Show file tree
Hide file tree
Showing 23 changed files with 170 additions and 45 deletions.
2 changes: 1 addition & 1 deletion app/app/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def preprocess(request):
header_msg, footer_msg, nav_salt = get_sitewide_announcements()

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

Expand Down
1 change: 1 addition & 0 deletions app/app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,7 @@ def callback(request):
SOCIAL_AUTH_GITHUB_SCOPE = ['read:user', 'user:email']
SOCIAL_AUTH_SANITIZE_REDIRECTS = True
SOCIAL_AUTH_REDIRECT_IS_HTTPS = True if ENV in ['prod', 'test', 'stage'] else False
SOCIAL_AUTH_FIELDS_STORED_IN_SESSION = ['state']

#custom scopes
SOCIAL_AUTH_GH_CUSTOM_KEY = GITHUB_CLIENT_ID
Expand Down
20 changes: 18 additions & 2 deletions app/assets/v2/js/cart-ethereum-polygon.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ Vue.component('grantsCartEthereumPolygon', {
const amount = requiredAmounts[key];
const formattedAmount = amount.toLocaleString(undefined, {
minimumFractionDigits: 2,
maximumFractionDigits: 2
maximumFractionDigits: 5
});

if (string === '') {
Expand Down Expand Up @@ -270,6 +270,10 @@ Vue.component('grantsCartEthereumPolygon', {
}
});

if (!ethereum.selectedAddress) {
throw new Error('Please unlock MetaMask to proceed with Polygon checkout');
}

// If user has enough balance within Polygon, cost equals the minimum amount
let { isBalanceSufficient, requiredAmounts } = await this.hasEnoughBalanceInPolygon();

Expand Down Expand Up @@ -322,6 +326,14 @@ Vue.component('grantsCartEthereumPolygon', {
// Get our donation inputs
const bulkTransaction = new web3.eth.Contract(bulkCheckoutAbi, bulkCheckoutAddressPolygon);
const donationInputsFiltered = this.getDonationInputs();

// Replace MATIC with 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE to enable
// the BulkCheckout contract handle it as a native transfer and not token
donationInputsFiltered.forEach(donation => {
if (donation.token === MATIC_ADDRESS) {
donation.token = ETH_ADDRESS;
}
});

// Send transaction
bulkTransaction.methods
Expand Down Expand Up @@ -357,6 +369,10 @@ Vue.component('grantsCartEthereumPolygon', {
if (this.cart.unsupportedTokens.length > 0) {
return;
}

if (!ethereum.selectedAddress) {
return;
}

let gasLimit = 0;

Expand Down Expand Up @@ -411,7 +427,7 @@ Vue.component('grantsCartEthereumPolygon', {
// const tokenAddr = currentValue.token?.toLowerCase();

if (currentValue.token === MATIC_ADDRESS) {
return accumulator + 25000; // MATIC donation gas estimate
return accumulator + 50000; // MATIC donation gas estimate
}

return accumulator + 70000; // generic token donation gas estimate
Expand Down
18 changes: 2 additions & 16 deletions app/assets/v2/js/cart.js
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ Vue.component('grants-cart', {
// If we have a cart where all donations are in Dai, we use a linear regression to
// estimate gas costs based on real checkout transaction data, and add a 50% margin
const donationCurrencies = this.donationInputs.map(donation => donation.token);
const daiAddress = this.getTokenByName('DAI').addr;
const daiAddress = this.getTokenByName('DAI')?.addr;
const isAllDai = donationCurrencies.every((addr) => addr === daiAddress);

if (isAllDai) {
Expand Down Expand Up @@ -799,23 +799,9 @@ Vue.component('grants-cart', {
decimals: 18,
priority: 1
};
} else if (name === 'MATIC' && isPolygon) {
return {
addr: MATIC_ADDRESS,
address: MATIC_ADDRESS,
name: 'MATIC',
symbol: 'MATIC',
decimals: 18,
priority: 1
};
}

if (isPolygon) {
token = this.filterByChainId.filter(token => token.name === name && token.networkId == this.networkId)[0];
return token;
}

return this.filterByChainId.filter(token => token.name === name)[0];
return this.filterByChainId.filter(token => token.name === name && token.networkId == this.networkId)[0];
},

async applyAmountToAllGrants(grant) {
Expand Down
8 changes: 8 additions & 0 deletions app/assets/v2/js/grants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,14 @@ if (document.getElementById('grants-showcase')) {
});
});
},
addCollectionToCart: async function(collection_id) {
const collectionDetailsURL = `/grants/v1/api/collections/${collection_id}`;
const collection = await fetchData(collectionDetailsURL, 'GET');

(collection.grants || []).forEach((grant) => {
CartData.addToCart(grant);
});
},
updateCartData: function(e) {
const grants_in_cart = (e && e.detail && e.detail.list && e.detail.list) || [];
const grant_ids_in_cart = grants_in_cart.map((grant) => grant.grant_id);
Expand Down
18 changes: 18 additions & 0 deletions app/avatar/migrations/0010_auto_20210924_0558.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.24 on 2021-09-24 05:58

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('avatar', '0009_avatartextoverlayinput'),
]

operations = [
migrations.AlterField(
model_name='baseavatar',
name='active',
field=models.BooleanField(db_index=True, default=False),
),
]
2 changes: 1 addition & 1 deletion app/avatar/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class BaseAvatar(SuperModel):

ICON_SIZE = (215, 215)

active = models.BooleanField(default=False)
active = models.BooleanField(default=False, db_index=True)
profile = models.ForeignKey(
'dashboard.Profile',
null=True,
Expand Down
23 changes: 23 additions & 0 deletions app/dashboard/migrations/0186_auto_20210924_0616.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 2.2.24 on 2021-09-24 06:16

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('dashboard', '0185_auto_20210823_2105'),
]

operations = [
migrations.AlterField(
model_name='tip',
name='comments_priv',
field=models.TextField(blank=True, db_index=True, default=''),
),
migrations.AlterField(
model_name='tip',
name='network',
field=models.CharField(db_index=True, default='', max_length=255),
),
]
4 changes: 2 additions & 2 deletions app/dashboard/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1658,7 +1658,7 @@ class SendCryptoAsset(SuperModel):
from_email = models.CharField(max_length=255, default='', blank=True)
from_username = models.CharField(max_length=255, default='', blank=True)
username = models.CharField(max_length=255, default='', blank=True) # to username
network = models.CharField(max_length=255, default='')
network = models.CharField(max_length=255, default='', db_index=True)
txid = models.CharField(max_length=255, default='')
receive_txid = models.CharField(max_length=255, default='', blank=True)
received_on = models.DateTimeField(null=True, blank=True)
Expand Down Expand Up @@ -1862,7 +1862,7 @@ def bounty(self):
class Tip(SendCryptoAsset):
""" Inherit from SendCryptoAsset base class, and extra fields that are needed for Tips. """
expires_date = models.DateTimeField(null=True, blank=True)
comments_priv = models.TextField(default='', blank=True)
comments_priv = models.TextField(default='', blank=True, db_index=True)
recipient_profile = models.ForeignKey(
'dashboard.Profile', related_name='received_tips', on_delete=models.SET_NULL, null=True, blank=True
)
Expand Down
12 changes: 12 additions & 0 deletions app/dashboard/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,18 @@ def record_visit(self, user_pk, profile_pk, ip_address, visitorId, useragent, re
utm=utm,
metadata=metadata,
)

# if the user is from a bad jurisdiction, block themm.
# or is named after an entity that is banned, block them
from dashboard.utils import should_be_blocked
if should_be_blocked(profile.handle):
from dashboard.models import BlockedUser
BlockedUser.objects.create(
handle=profile.handle,
comments='should_be_blocked',
active=True,
user=user,
)
except Exception as e:
logger.exception(e)

Expand Down
2 changes: 2 additions & 0 deletions app/dashboard/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,9 @@ def is_blocked(handle):
is_on_blocked_list = BlockedUser.objects.filter(handle=handle.lower(), active=True).exists()
if is_on_blocked_list:
return True
return False

def should_be_blocked(handle):
# check banned country list
profiles = Profile.objects.filter(handle=handle.lower())
if profiles.exists():
Expand Down
8 changes: 2 additions & 6 deletions app/grants/templates/grants/components/collection.html
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,8 @@ <h2 class="h5 gc-font-base">
<input type="hidden" :id="`collection-${collection.id}`" :value="`https://gitcoin.co/grants/explorer/?collection_id=${collection.id}`">
</button>

<template v-if="$parent.activeCollection">
<button @click.stop="addToCart()" class="btn btn-primary ml-1" style="flex: 1 1 0px;">
<i class="fas fa-fw fa-cart-plus" aria-hidden="true"></i> Add to Cart
</button>
</template>
<template v-else>

<template>
<a class="btn btn-primary ml-1" :href="`/grants/explorer/?collection_id=${collection.id}`" style="flex: 1 1 0px;" v-if="$parent.isLandingPage">
<i class="fas fa-fw fa-arrow-right"></i> View
</a>
Expand Down
14 changes: 9 additions & 5 deletions app/grants/templates/grants/explorer.html
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@
class="far fa-fw fa-search font-smaller-3 position-absolute text-grey-300"
:style="(searchVisible ? 'top: 10px;margin-left: 7px;left: 34px;' : 'top: 19px; margin-left: 7px;')"
></i>
<input class="form-control form-control-sm rounded-pill pl-4" placeholder="Search..." type="search" @click="searchVisible=!searchVisible" v-model="params.keyword" @input="changeQuery({page: 1})">
<input class="form-control form-control-sm rounded-pill pl-4" placeholder="Search..." type="search" @click="searchVisible=!searchVisible" v-model="params.keyword" @input="changeQuery({page: 1})" @keyup.enter="changeQuery({page: 1})">
<div class="navCart dropdown gc-cart" v-if="!searchVisible && sticky_active">
<a href="" class="gc-cart__icon d-block" role="button" @click="$refs.navCart.init()"
data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" style="padding: 0.3rem 1rem;">
Expand Down Expand Up @@ -281,10 +281,14 @@

{% include 'grants/shared/top-filters.html' %}

<template v-if="isGrantExplorer && !isGrantCollectionExplorer">
<!-- {% include 'grants/shared/active_clr_round.html'%} -->
</template>
<button class="btn btn-outline-gc-grey btn-sm mb-2" v-if="grantsHasPrev" @click="unshiftGrants(lowestPage-1)">Load previous page</button>
<div class="d-flex">
<button class="btn btn-outline-gc-grey btn-sm mb-2" v-if="grantsHasPrev" @click="unshiftGrants(lowestPage-1)">Load previous page</button>
<template v-if="params.collection_id">
<button @click.stop="addCollectionToCart(params.collection_id)" class="btn btn-sm btn-primary mb-2 ml-auto">
<i class="fas fa-fw fa-cart-plus" aria-hidden="true"></i> Add Collection to Cart
</button>
</template>
</div>
<div class="infinite-container row" v-if="grants">
<div :class="`col-12 ${view == 'grid' ? 'col-md-6 col-xl-4' : ''} mb-4 infinite-item grant-card`" v-for="(grant, id) in grants">
<a class="text-decoration-none" :href="grant.details_url">
Expand Down
2 changes: 2 additions & 0 deletions app/grants/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,8 @@ def toggle_user_sybil(sybil_users, non_sybil_users):
print(f"error: unable to mark user ${user.get('handle')} as sybil. {e}")

if non_sybil_users:
# exclude squelches added by manual
squelched_profiles = squelched_profiles.exclude(label='Manual')
# iterate and remove sybil from user
for user in non_sybil_users:
try:
Expand Down
8 changes: 4 additions & 4 deletions app/grants/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def helper_grants_output(request, meta_data, addresses, GAK=None):
hide_wallet_address_anonymized_sql = "AND contributor_profile_id NOT IN (select id from dashboard_profile where hide_wallet_address_anonymized)"


@ratelimit(key='ip', rate='10/m', method=ratelimit.UNSAFE, block=True)
@ratelimit(key='ip', rate='2/m', method=ratelimit.UNSAFE, block=True)
def contribution_addr_from_grant_as_json(request, grant_id):

# return all contirbutor addresses to the grant
Expand All @@ -204,7 +204,7 @@ def contribution_addr_from_grant_as_json(request, grant_id):
return helper_grants_output(request, meta_data, earnings, GAK)


@ratelimit(key='ip', rate='10/m', method=ratelimit.UNSAFE, block=True)
@ratelimit(key='ip', rate='2/m', method=ratelimit.UNSAFE, block=True)
def contribution_addr_from_grant_during_round_as_json(request, grant_id, round_id):

# return all contirbutor addresses to the grant
Expand Down Expand Up @@ -234,7 +234,7 @@ def contribution_addr_from_grant_during_round_as_json(request, grant_id, round_i
}
return helper_grants_output(request, meta_data, earnings, GAK)

@ratelimit(key='ip', rate='10/m', method=ratelimit.UNSAFE, block=True)
@ratelimit(key='ip', rate='1/m', method=ratelimit.UNSAFE, block=True)
def contribution_info_from_grant_during_round_as_json(request, grant_id, round_id):

# return all contirbutor addresses to the grant
Expand Down Expand Up @@ -264,7 +264,7 @@ def contribution_info_from_grant_during_round_as_json(request, grant_id, round_i
INNER JOIN dashboard_profile on dashboard_profile.id = contributor_profile_id
where
grants_subscription.created_on BETWEEN '{start}' AND '{end}' and grant_id = {grant_id}
{hide_wallet_address_anonymized_sql}
AND hide_wallet_address_anonymized = false
order by grants_subscription.id desc
LIMIT 10
"""
Expand Down
18 changes: 18 additions & 0 deletions app/kudos/migrations/0020_auto_20210924_0616.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.24 on 2021-09-24 06:16

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('kudos', '0019_tokenrequest_gas_price_overide'),
]

operations = [
migrations.AlterField(
model_name='kudostransfer',
name='network',
field=models.CharField(db_index=True, default='', max_length=255),
),
]
4 changes: 1 addition & 3 deletions app/marketing/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

redis = RedisService().redis

rate_limit = '30000/s' if settings.FLUSH_QUEUE or settings.MARKETING_FLUSH_QUEUE else settings.MARKETING_QUEUE_RATE_LIMIT
rate_limit = '300000/s' if settings.FLUSH_QUEUE or settings.MARKETING_FLUSH_QUEUE else settings.MARKETING_QUEUE_RATE_LIMIT

@app.shared_task(bind=True, rate_limit=rate_limit, soft_time_limit=600, time_limit=660, max_retries=1)
def new_bounty_daily(self, email_subscriber_id, retry: bool = True) -> None:
Expand All @@ -24,11 +24,9 @@ def new_bounty_daily(self, email_subscriber_id, retry: bool = True) -> None:

# dont send emails on this server, dispurse them back into the queue
if settings.FLUSH_QUEUE:
redis.sadd('bounty_daily_retry', email_subscriber_id)
return

if settings.MARKETING_FLUSH_QUEUE:
redis.sadd('bounty_daily_retry', email_subscriber_id)
return

# actually do the task
Expand Down
6 changes: 5 additions & 1 deletion app/marketing/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,11 @@ def get_or_save_email_subscriber(email, source, send_slack_invite=True, profile=

created = False
try:
es, created = EmailSubscriber.objects.update_or_create(email__iexact=email, defaults=defaults)
es = EmailSubscriber.objects.filter(email=email).first()
if not es:
es = EmailSubscriber.objects.filter(email__iexact=email).first()
if not es:
es, created = EmailSubscriber.objects.update_or_create(email__iexact=email, defaults=defaults)
# print("EmailSubscriber:", es, "- created" if created else "- updated")
except EmailSubscriber.MultipleObjectsReturned:
email_subscriber_ids = EmailSubscriber.objects.filter(email__iexact=email) \
Expand Down
2 changes: 1 addition & 1 deletion app/quests/quest_types/quiz_style.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def details(request, quest):
answer_level_seconds_to_respond = payload.get('seconds_to_respond', None)
if answer_level_seconds_to_respond:
this_time_per_answer = answer_level_seconds_to_respond
time_used = (timezone.now() - qa.modified_on).seconds
time_used = (timezone.now() - qa.modified_on).seconds if qa else timezone.now()
is_out_of_time = time_used > this_time_per_answer + time_per_answer_buffer
if is_out_of_time:
# fix for silly issue where the time used is almost exactly
Expand Down
2 changes: 1 addition & 1 deletion app/retail/templates/results.html
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ <h3 class="single-stat__title">${{ grants_gmv }}</h3>
<img src="{% static "v2/images/results/matching_rounds.svg" %}" />
<h3 class="single-stat__title">{{ num_matching_rounds|floatformat:0 }}</h3>
<p class="single-stat__subtitle">{% trans "No. Matching Rounds" %}</p>
<p class="single-stat__fineprint">(<a href="https://twitter.com/owocki/status/1414555147506696196" target="new">see the growth of these matching rounds</a>)</p>
<p class="single-stat__fineprint">(<a href="https://twitter.com/owocki/status/1441415242009886723" target="new">see the growth of these matching rounds</a>)</p>
</div>
<div class="single-stat">
<img src="{% static "v2/images/results/avg-contribution.svg" %}" />
Expand Down
18 changes: 18 additions & 0 deletions app/revenue/migrations/0003_auto_20210924_0616.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 2.2.24 on 2021-09-24 06:16

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('revenue', '0002_auto_20200605_1302'),
]

operations = [
migrations.AlterField(
model_name='digitalgoodpurchase',
name='network',
field=models.CharField(db_index=True, default='', max_length=255),
),
]
Loading

0 comments on commit 0717294

Please sign in to comment.