{% trans 'Provide sustainable funding for Open Source
+ {% if matchpledges %}
+
+
+
Matching Partners
+
A special thanks to the following partners who have offered to match contributions to Gitcoin Grants. (Read Announcement Here)
+ {% for mp in matchpledges %}
+
+
@{{mp.profile.handle}}
+
+
${{mp.amount|floatformat}}
+
+ {% endfor %}
+
+
+ {% endif %}
+
diff --git a/app/grants/templates/grants/profile/body.html b/app/grants/templates/grants/profile/body.html
index bb3fcc777f0..9ce1d2cb752 100644
--- a/app/grants/templates/grants/profile/body.html
+++ b/app/grants/templates/grants/profile/body.html
@@ -39,11 +39,17 @@
{% trans "Transaction History" %}
{{ transaction.grant.title }}
- {{ transaction.sub.amount_per_period|floatformat:4|intcomma }} {{ transaction.sub.token_symbol }} / {{ transaction.sub.frequency }} {{ transaction.sub.frequency_unit }}
+
+ {{ transaction.sub.amount_per_period|floatformat:4|intcomma }} {{ transaction.sub.token_symbol }}
+ {% if transaction.sub.num_tx_approved > 1 %}
+ / {{ transaction.sub.frequency }} {{ transaction.sub.frequency_unit }},
+ {% endif %}
+ {{transaction.sub.num_tx_approved|floatformat}} time{{ transaction.sub.num_tx_approved|pluralize }}
+
-
+
View Etherscan
diff --git a/app/grants/views.py b/app/grants/views.py
index 897e132d635..35be4874667 100644
--- a/app/grants/views.py
+++ b/app/grants/views.py
@@ -40,7 +40,7 @@
from dashboard.models import Profile
from gas.utils import conf_time_spread, eth_usd_conv_rate, gas_advisories, recommend_min_gas_price_to_confirm_in_time
from grants.forms import MilestoneForm
-from grants.models import Contribution, Grant, Milestone, Subscription, Update
+from grants.models import Contribution, Grant, MatchPledge, Milestone, Subscription, Update
from marketing.mails import (
change_grant_owner_accept, change_grant_owner_reject, change_grant_owner_request, grant_cancellation, new_grant,
new_supporter, subscription_terminated, support_cancellation, thank_you_for_supporting,
@@ -61,7 +61,7 @@ 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')
+ sort = request.GET.get('sort_option', '-clr_matching')
network = request.GET.get('network', 'mainnet')
keyword = request.GET.get('keyword', '')
state = request.GET.get('state', 'active')
@@ -81,6 +81,7 @@ def grants(request):
'sort': sort,
'network': network,
'keyword': keyword,
+ 'matchpledges': MatchPledge.objects.filter(active=True).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'),
@@ -108,6 +109,7 @@ def grant_details(request, grant_id, grant_slug):
cancelled_subscriptions = grant.subscriptions.filter(Q(active=False, error=False) | Q(error=True))
contributions = Contribution.objects.filter(subscription__in=grant.subscriptions.all())
user_subscription = grant.subscriptions.filter(contributor_profile=profile, active=True).first()
+ user_non_errored_subscription = grant.subscriptions.filter(contributor_profile=profile, active=True, error=False).first()
add_cancel_params = user_subscription
except Grant.DoesNotExist:
raise Http404
@@ -165,6 +167,7 @@ def grant_details(request, grant_id, grant_slug):
'cancelled_subscriptions': cancelled_subscriptions,
'contributions': contributions,
'user_subscription': user_subscription,
+ 'user_non_errored_subscription': user_non_errored_subscription,
'is_admin': is_admin,
'grant_is_inactive': not grant.active,
'updates': updates,
@@ -242,6 +245,13 @@ def grant_new(request):
if 'contract_address' in request.POST:
tx_hash = request.POST.get('transaction_hash', '')
+ if not tx_hash:
+ return JsonResponse({
+ 'success': False,
+ 'info': 'no tx hash',
+ 'url': None,
+ })
+
grant = Grant.objects.filter(deploy_tx_id=tx_hash).first()
grant.contract_address = request.POST.get('contract_address', '')
print(tx_hash, grant.contract_address)
@@ -346,7 +356,7 @@ def grant_fund(request, grant_id, grant_slug):
return TemplateResponse(request, 'grants/shared/error.html', params)
active_subscription = Subscription.objects.select_related('grant').filter(
- grant=grant_id, active=True, contributor_profile=request.user.profile
+ grant=grant_id, active=True, error=False, contributor_profile=request.user.profile
)
if active_subscription:
@@ -378,6 +388,13 @@ def grant_fund(request, grant_id, grant_slug):
subscription.grant = grant
subscription.save()
+ # one time payments
+ if subscription.num_tx_approved == '1':
+ subscription.successful_contribution(subscription.new_approve_tx_id);
+ subscription.error = True #cancel subs so it doesnt try to bill again
+ subscription.subminer_comments = "skipping subminer bc this is a 1 and done subscription, and tokens were alredy sent"
+ subscription.save()
+
messages.info(
request,
_('Your subscription has been created. It will bill within the next 5 minutes or so. Thank you for supporting Open Source !')
@@ -506,7 +523,7 @@ def profile(request):
sub_contributions = []
contributions = []
- for contribution in Contribution.objects.filter(subscription__contributor_profile=profile):
+ for contribution in Contribution.objects.filter(subscription__contributor_profile=profile).order_by('-pk'):
instance = {
"cont": contribution,
"sub": contribution.subscription,
@@ -550,7 +567,6 @@ def quickstart(request):
return TemplateResponse(request, 'grants/quickstart.html', params)
-@cached_view(timeout=60)
def leaderboard(request):
"""Display leaderboard."""
params = {
diff --git a/app/inbox/migrations/0002_auto_20190223_2158.py b/app/inbox/migrations/0002_auto_20190223_2158.py
new file mode 100644
index 00000000000..8d8f983ff15
--- /dev/null
+++ b/app/inbox/migrations/0002_auto_20190223_2158.py
@@ -0,0 +1,23 @@
+# Generated by Django 2.1.2 on 2019-02-23 21:58
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('inbox', '0001_initial'),
+ ]
+
+ operations = [
+ migrations.AlterField(
+ model_name='notification',
+ name='cta_url',
+ field=models.URLField(blank=True, max_length=500),
+ ),
+ migrations.AlterField(
+ model_name='notification',
+ name='message_html',
+ field=models.CharField(blank=True, help_text='Html message', max_length=2000),
+ ),
+ ]
diff --git a/app/inbox/models.py b/app/inbox/models.py
index ccc24e0b40c..2c5f1a9d575 100644
--- a/app/inbox/models.py
+++ b/app/inbox/models.py
@@ -56,12 +56,12 @@ class Notification(SuperModel):
('update_milestone', 'Updated Milestone'),
('new_kudos', 'New Kudos'),
)
- cta_url = models.URLField(max_length=255, blank=True)
+ cta_url = models.URLField(max_length=500, blank=True)
cta_text = models.CharField(
max_length=50,
choices=NOTIFICATION_TYPES
)
- message_html = models.CharField(max_length=255, blank=True, help_text=_("Html message"))
+ message_html = models.CharField(max_length=2000, blank=True, help_text=_("Html message"))
is_read = models.BooleanField(default=False)
to_user = models.ForeignKey(
get_user_model(),
diff --git a/app/kudos/kudos.yaml b/app/kudos/kudos.yaml
index 11b82a8c8ed..df501ee7915 100644
--- a/app/kudos/kudos.yaml
+++ b/app/kudos/kudos.yaml
@@ -3066,6 +3066,46 @@
- alchemy
- code
image: alchemist.svg
+- name: logical_spock
+ to_address: 0xb9c4668CEf8B52b1A0751Dcf14605Cd90F8c9Fce
+ artist: mehul0698
+ description: For those who have a very good logic in solving the problem/issue in hand.
+ priceFinney: 50
+ numClonesAllowed: 100
+ tags:
+ - programming
+ - lanugages
+ - c++
+ - javascript
+ - python
+ - java
+ - php
+ - go
+ - ruby
+ - algorithms
+ - compliments
+ image: logical_spock.svg
+- name: nyan_cat
+ to_address: 0x4b00a17a8A4c7dC2f71777207B1C1Bd6C132D394
+ artist: cryptodesign
+ description: Everywhere you go, you leave a rainbow trail of great work behind you.
+ priceFinney: 4
+ numClonesAllowed: 150
+ tags:
+ - nyan
+ - cat
+ - rainbow
+ image: nyan.svg
+- name: show_me_what_you_got
+ artist: emiwatanabe422
+ description: You showed me what you got!
+ priceFinney: 20
+ platform: gitcoin
+ numClonesAllowed: 500
+ tags:
+ - just for fun
+ - meme
+ image: ShowMeWhatYouGot.svg
diff --git a/app/kudos/management/commands/sync_kudos.py b/app/kudos/management/commands/sync_kudos.py
index 5327b3a3806..da1f5933f6e 100644
--- a/app/kudos/management/commands/sync_kudos.py
+++ b/app/kudos/management/commands/sync_kudos.py
@@ -28,6 +28,7 @@
import web3
from kudos.models import Token
from kudos.utils import KudosContract
+from python_http_client.exceptions import HTTPError
# from web3.middleware import local_filter_middleware
@@ -83,6 +84,8 @@ def opensea_sync(self, kudos_contract, start_id):
kudos_contract.sync_db(kudos_id=int(asset_token_id), txid=transaction_hash)
except IndexError:
continue
+ except HTTPError:
+ logger.debug(e)
except Exception as e:
logger.error(e)
diff --git a/app/kudos/views.py b/app/kudos/views.py
index 89b00338116..d494614290c 100644
--- a/app/kudos/views.py
+++ b/app/kudos/views.py
@@ -661,7 +661,7 @@ def receive_bulk(request, secret):
emails=[request.user.email],
# For kudos, `token` is a kudos.models.Token instance.
kudos_token_cloned_from=coupon.token,
- amount=0,
+ amount=coupon.token.price_in_eth,
comments_public=coupon.comments_to_put_in_kudos_transfer,
ip=ip_address,
github_url='',
diff --git a/app/marketing/stats.py b/app/marketing/stats.py
index ce39cf32630..1491eed46e4 100644
--- a/app/marketing/stats.py
+++ b/app/marketing/stats.py
@@ -280,7 +280,7 @@ def grants():
from grants.models import Contribution
val = 0
for contrib in Contribution.objects.filter(subscription__grant__network='mainnet'):
- value_in_usdt = contrib.subscription.value_usdt
+ value_in_usdt = contrib.subscription.amount_per_period_usdt
if value_in_usdt:
val += value_in_usdt
diff --git a/app/marketing/views.py b/app/marketing/views.py
index 76f6facc503..3de750faef3 100644
--- a/app/marketing/views.py
+++ b/app/marketing/views.py
@@ -659,7 +659,6 @@ def _leaderboard(request):
return leaderboard(request, '')
-@cached_view(timeout=60*16)
def leaderboard(request, key=''):
"""Display the leaderboard for top earning or paying profiles.
diff --git a/app/perftools/management/commands/create_results.py b/app/perftools/management/commands/create_results.py
index 363ab56a161..5b5871a8fc3 100644
--- a/app/perftools/management/commands/create_results.py
+++ b/app/perftools/management/commands/create_results.py
@@ -46,7 +46,7 @@ class Command(BaseCommand):
help = 'generates some /results data'
def handle(self, *args, **options):
- keywords = [''] + programming_languages
+ keywords = ['']
# DEBUG OPTIONS
# keywords = ['']
view = 'results'
diff --git a/app/retail/templates/emails/bounty_roundup.html b/app/retail/templates/emails/bounty_roundup.html
index 956757fe07e..93075ee9486 100644
--- a/app/retail/templates/emails/bounty_roundup.html
+++ b/app/retail/templates/emails/bounty_roundup.html
@@ -131,7 +131,7 @@
{{ package.title }}
{% endif %}
diff --git a/app/retail/templates/results.html b/app/retail/templates/results.html
index ceb49586d14..dcfcc6a6792 100644
--- a/app/retail/templates/results.html
+++ b/app/retail/templates/results.html
@@ -58,9 +58,12 @@
{% trans "Broken Down by Mont
{% trans "and by Type" %}
-
{% trans "Bounties + Tips" %}
-
{% trans "Grants" %}
-
{% trans "Kudos" %}
+
{% trans "Bounties" %}
+
{% trans "Tips" %}
+
{% trans "Grants" %}
+
{% trans "Kudos" %}
+
{% trans "Ads" %}
+
{% trans "Ecosystem" %}
diff --git a/app/retail/templates/shared/footer.html b/app/retail/templates/shared/footer.html
index bf7273275aa..be518603d78 100644
--- a/app/retail/templates/shared/footer.html
+++ b/app/retail/templates/shared/footer.html
@@ -55,21 +55,23 @@
diff --git a/app/retail/utils.py b/app/retail/utils.py
index 652cc54ebff..834c9db8081 100644
--- a/app/retail/utils.py
+++ b/app/retail/utils.py
@@ -81,15 +81,20 @@ def strip_double_chars(txt, char=' '):
def get_bounty_history_row(label, date, keyword):
bounties = get_bounty_history_at_date(['done'], date, keyword)
- tips = get_tip_history_at_date(date, keyword)
+ ecosystem = get_ecosystem_history_at_date(date, keyword)
+ codefund = get_codefund_history_at_date(date, keyword)
+ tips = get_tip_history_at_date(date, keyword) - ecosystem
core_platform = bounties + tips
- print(label, date, core_platform, keyword, bounties, tips)
+ print(label, date, core_platform, keyword, bounties, tips, ecosystem)
return [
label,
- core_platform,
+ bounties,
+ tips,
get_grants_history_at_date(date, keyword),
get_kudos_history_at_date(date, keyword),
+ codefund,
+ ecosystem,
]
@@ -122,6 +127,40 @@ def get_kudos_history_at_date(date, keyword):
return get_cryptoasset_history_at_date(date, keyword, 'kudos')
+def get_ecosystem_history_at_date(date, keyword):
+ date = date.replace(tzinfo=None)
+ amount = 0
+ if date > timezone.datetime(2019, 1, 23):
+ amount += 184043 + 24033
+ if date > timezone.datetime(2018, 12, 23):
+ amount += 51087.23
+ return amount
+
+
+def get_codefund_history_at_date(date, keyword):
+ date = date.replace(tzinfo=None)
+ amount = 0
+ # July => Feb 2019
+ # $5,500.00 $4,400.00 $9,000.00 $8,500.00 $7,450.00 $6,150.00 $9,700.00 $6,258.31
+ if date > timezone.datetime(2018, 7, 23):
+ amount += 5500
+ if date > timezone.datetime(2018, 8, 23):
+ amount += 4400
+ if date > timezone.datetime(2018, 9, 23):
+ amount += 9000
+ if date > timezone.datetime(2018, 10, 23):
+ amount += 8500
+ if date > timezone.datetime(2018, 11, 23):
+ amount += 7450
+ if date > timezone.datetime(2018, 12, 23):
+ amount += 6150
+ if date > timezone.datetime(2019, 1, 23):
+ amount += 9700
+ if date > timezone.datetime(2019, 2, 23):
+ amount += 6258 # MTD
+ return amount
+
+
def get_tip_history_at_date(date, keyword):
return get_cryptoasset_history_at_date(date, keyword, 'tips')
@@ -289,14 +328,14 @@ def get_bounty_median_turnaround_time(func='turnaround_time_started', keyword=No
def get_bounty_history(keyword=None, cumulative=True):
bh = [
- ['', 'Core Platform', 'Grants', 'Kudos'],
+ ['', 'Bounties', 'Tips', 'Grants', 'Kudos', 'Ads', 'Ecosystem'],
]
initial_stats = [
- ["December 2017", 2011 + 5534, 0, 0],
- ["January 2018", 5093 + 15930, 0, 0],
- ["February 2018", 7391 + 16302, 0, 0],
- ["March 2018", 8302 + 26390, 0, 0],
- ["April 2018", 10109 + 37342, 0, 0],
+ ["December 2017", 5534, 2011, 0, 0, 0, 0],
+ ["January 2018", 15930, 5093, 0, 0, 0, 0],
+ ["February 2018", 16302, 7391, 0, 0, 0, 0],
+ ["March 2018", 26390, 8302, 0, 0, 0, 0],
+ ["April 2018", 37342, 10109, 0, 0, 0, 0],
]
if not keyword:
bh = bh + initial_stats
@@ -429,7 +468,15 @@ def build_stat_results(keyword=None):
])
total_grants_usd = get_grants_history_at_date(timezone.now(), [])
total_kudos_usd = get_kudos_history_at_date(timezone.now(), [])
- context['universe_total_usd'] = float(total_bounties_usd) + float(total_tips_usd) + float(total_grants_usd) + float(total_kudos_usd)
+ total_codefund_usd = get_codefund_history_at_date(timezone.now(), '')
+ all_platforms = [
+ float(total_bounties_usd),
+ float(total_tips_usd),
+ float(total_grants_usd),
+ float(total_kudos_usd),
+ float(total_codefund_usd)
+ ]
+ context['universe_total_usd'] = sum(all_platforms)
pp.profile_time('universe_total_usd')
context['max_bounty_history'] = float(context['universe_total_usd']) * .15
context['bounty_abandonment_rate'] = bounty_abandonment_rate
diff --git a/app/retail/views.py b/app/retail/views.py
index 87818c200ca..bed461d1455 100644
--- a/app/retail/views.py
+++ b/app/retail/views.py
@@ -373,7 +373,6 @@ def funder_bounties(request):
return TemplateResponse(request, 'bounties/funder.html', context)
-@cached_view(timeout=60 * 10)
def contributor_bounties(request, tech_stack):
slides = [
@@ -880,10 +879,9 @@ def results(request, keyword=None):
return TemplateResponse(request, 'results.html', context)
-@cached_view_as(Activity.objects.all().order_by('-created'))
def activity(request):
"""Render the Activity response."""
- page_size = 300
+ page_size = 15
activities = Activity.objects.all().order_by('-created')
p = Paginator(activities, page_size)
page = request.GET.get('page', 1)
diff --git a/scripts/debug/update_grant_clr_amounts.py b/scripts/debug/update_grant_clr_amounts.py
new file mode 100644
index 00000000000..dd2d430c66c
--- /dev/null
+++ b/scripts/debug/update_grant_clr_amounts.py
@@ -0,0 +1,12 @@
+from grants.models import Grant
+
+eles = 'Prysm by Prysmatic Labs $4,306.03','MolochDAO $2,839.74','Uniswap $2,121.57','Cryptoeconomics.study - Free, Open-Source Blockchain Course $2,071.84','Lodestar (eth2.0 client) $1,702.61','ZoKrates $1,604.32','Plasma Group $1,572.80','Lighthouse: Ethereum 2.0 Client $1,460.16','EthHub - Ethereum Information Hub $1,407.90','ethers.js - Complete, Simple and Tiny $1,357.51','The Gitcoin Open Source Support Fund $999.87','Burner Wallet $984.69','Connext Network $738.26','Implement support for asyncio using Web3.py $542.66','Zero Knowledge Podcast $374.30','Gossipsub and Eth 2 / Shasper Development $344.54','ETH2.0 Implementers Call Notes $202.83','Yeeth $145.38','FISSION Codes $85.66','Vipnode $83.44','Whiteblock Testing $22.94','Ethereum All Core Devs community project management $17.11','Peepeth: social network for a better world $6.73','GrantOps $6.42','EVM Evolution $0.64','ChainID Network $0.06'
+for ele in eles:
+ arr = ele.split('$')
+ title = arr[0].strip()
+ amount = float(arr[1].replace(",", '').strip())
+
+ grant = Grant.objects.filter(title=title, active=True).first()
+ print(title,grant.pk, amount)
+ grant.clr_matching = amount
+ grant.save()
diff --git a/scripts/deploy.bash b/scripts/deploy.bash
index b9481110aec..bd21f7df5a5 100755
--- a/scripts/deploy.bash
+++ b/scripts/deploy.bash
@@ -80,7 +80,11 @@ fi
# let gunicorn know its ok to restart
if ! [ "$JOBS_NODE" ]; then
echo "- gunicorn"
- sudo systemctl restart gunicorn
+ for pid in $(pgrep -fl "gunicorn: worke" | awk '{print $1}'); do
+ sudo kill -1 $pid
+ sleep 0.5
+ done
+
fi
# invalidate cloudfront