Skip to content

Commit

Permalink
fixes #8039 (#8394)
Browse files Browse the repository at this point in the history
* adds trending kudos/quests to activty feed

* fixes grants api (#8392)

* just fixes some dumb kudos display issues

* fixes slowness of results page

* fixes #8039

* docs
  • Loading branch information
owocki authored Feb 16, 2021
1 parent 011591f commit 615b0f3
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 49 deletions.
5 changes: 4 additions & 1 deletion app/grants/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

from grants.views import (
add_grant_from_collection, bulk_fund, bulk_grants_for_cart, cancel_grant_v1, clr_grants, collection_thumbnail,
contribute_to_grants_v1, contribution_addr_from_all_as_json, contribution_addr_from_grant_as_json,
contribute_to_grants_v1, contribution_addr_from_all_as_json, contribution_info_from_grant_during_round_as_json, contribution_addr_from_grant_as_json,
contribution_addr_from_grant_during_round_as_json, contribution_addr_from_round_as_json, create_matching_pledge_v1,
flag, get_collection, get_collections_list, get_ethereum_cart_data, get_grant_payload, get_grants,
get_interrupted_contributions, get_replaced_tx, grant_activity, grant_categories, grant_details, grant_details_api,
Expand Down Expand Up @@ -110,4 +110,7 @@
path('v1/api/export_addresses/round<int:round_id>.json', contribution_addr_from_round_as_json, name='contribution_addr_from_round_as_json'),
path('v1/api/export_addresses/grant<int:grant_id>.json', contribution_addr_from_grant_as_json, name='contribution_addr_from_grant_as_json'),
path('v1/api/export_addresses/grant<int:grant_id>_round<int:round_id>.json', contribution_addr_from_grant_during_round_as_json, name='contribution_addr_from_grant_during_round_as_json'),
path('v1/api/export_info/grant<int:grant_id>_round<int:round_id>.json', contribution_info_from_grant_during_round_as_json, name='contribution_addr_from_grant_during_round_as_json'),


]
106 changes: 65 additions & 41 deletions app/grants/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,39 +249,18 @@ def helper_grants_round_start_end_date(request, round_id):
print(e)
return start, end

def helper_contributions_to_earnings(_contributions):
from dashboard.models import Earning #avoid circulr import
return Earning.objects.filter(
source_type=ContentType.objects.get(app_label='grants', model='contribution'),
source_id__in=_contributions,
)

def helper_earnings_to_addr_list(earnings):
items = earnings.values_list('history__payload__from', flat=True)
return list(items)

def helper_grants_output(request, meta_data, earnings):
def helper_grants_output(request, meta_data, addresses):

# gather_stats
tx_count_start = earnings.count()
addr_count_start = len(set([ele for ele in helper_earnings_to_addr_list(earnings)]))

# privacy first
earnings = earnings.exclude(from_profile__hide_wallet_address_anonymized=True)

# gather metadata, before & aftter filtering
addresses = list(set([ele for ele in helper_earnings_to_addr_list(earnings) if ele]))
addr_count_end = len(set(addresses))
add_count = len(addresses)

response = {
'meta': {
'generated_at': request.build_absolute_uri(),
'generated_on': timezone.now().strftime("%Y-%m-%d"),
'stat':{
'transactions_found': tx_count_start,
'unique_addresses_found': addr_count_start,
'unique_addresses_found_after_privacy_preferences': addr_count_end,
'unique_addresses_removed_per_privacy_preferences': addr_count_start - addr_count_end,
'unique_addresses_found': add_count,
},
'meta': meta_data,
},
Expand All @@ -292,6 +271,7 @@ def helper_grants_output(request, meta_data, earnings):

grants_data_release_date = timezone.datetime(2020, 10, 22)

hide_wallet_address_anonymized_sql = "AND contributor_profile_id NOT IN (select id from dashboard_profile where hide_wallet_address_anonymized)"
@login_required
@cached_view(timeout=3600)
def contribution_addr_from_grant_as_json(request, grant_id):
Expand All @@ -308,10 +288,8 @@ def contribution_addr_from_grant_as_json(request, grant_id):
'msg': f'not_authorized, check back at {grants_data_release_date.strftime("%Y-%m-%d")}'
}, safe=False)

_contributions = Contribution.objects.filter(
subscription__network='mainnet', subscription__grant__id=grant_id
)
earnings = helper_contributions_to_earnings(_contributions)
query = f"select distinct contributor_address from grants_subscription where grant_id = '{grant_id}' {hide_wallet_address_anonymized_sql}"
earnings = query_to_results(query)
meta_data = {
'grant': grant_id,
}
Expand All @@ -334,13 +312,53 @@ def contribution_addr_from_grant_during_round_as_json(request, grant_id, round_i
'msg': f'not_authorized, check back at {grants_data_release_date.strftime("%Y-%m-%d")}'
}, safe=False)

start, end = helper_grants_round_start_end_date(request, round_id)
query = f"select distinct contributor_address from grants_subscription where created_on BETWEEN '{start}' AND '{end}' and grant_id = '{grant_id}' {hide_wallet_address_anonymized_sql}"
earnings = query_to_results(query)

meta_data = {
'start': start.strftime("%Y-%m-%d"),
'end': end.strftime("%Y-%m-%d"),
'round': round_id,
'grant': grant_id,
}
return helper_grants_output(request, meta_data, earnings)

@login_required
@cached_view(timeout=3600)
def contribution_info_from_grant_during_round_as_json(request, grant_id, round_id):

# return all contirbutor addresses to the grant
grant = Grant.objects.get(pk=grant_id)

if not grant.is_on_team(request.user.profile) and not request.user.is_staff:
return JsonResponse({
'msg': 'not_authorized, you must be a team member of this grant'
}, safe=False)
if timezone.now().timestamp() < grants_data_release_date.timestamp() and not request.user.is_staff:
return JsonResponse({
'msg': f'not_authorized, check back at {grants_data_release_date.strftime("%Y-%m-%d")}'
}, safe=False)

start, end = helper_grants_round_start_end_date(request, round_id)
_contributions = Contribution.objects.filter(
subscription__network='mainnet', subscription__grant__id=grant_id,
created_on__gt=start, created_on__lt=end
)
earnings = helper_contributions_to_earnings(_contributions)
query = f"""
select
md5(grants_subscription.id::varchar(255)) as id,
dashboard_profile.handle,
CONCAT('https://gitcoin.co/dynamic/avatar/', dashboard_profile.handle) as url,
comments
from grants_subscription
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}
order by grants_subscription.id desc
"""
print(query)
earnings = query_to_results(query)

meta_data = {
'start': start.strftime("%Y-%m-%d"),
'end': end.strftime("%Y-%m-%d"),
Expand All @@ -349,6 +367,7 @@ def contribution_addr_from_grant_during_round_as_json(request, grant_id, round_i
}
return helper_grants_output(request, meta_data, earnings)


@login_required
@cached_view(timeout=3600)
def contribution_addr_from_round_as_json(request, round_id):
Expand All @@ -359,10 +378,8 @@ def contribution_addr_from_round_as_json(request, round_id):
}, safe=False)

start, end = helper_grants_round_start_end_date(request, round_id)
_contributions = Contribution.objects.filter(
subscription__network='mainnet', created_on__gt=start, created_on__lt=end
)
earnings = helper_contributions_to_earnings(_contributions)
query = f"select distinct contributor_address from grants_subscription where created_on BETWEEN '{start}' AND '{end}' {hide_wallet_address_anonymized_sql}"
earnings = query_to_results(query)
meta_data = {
'start': start.strftime("%Y-%m-%d"),
'end': end.strftime("%Y-%m-%d"),
Expand All @@ -371,6 +388,15 @@ def contribution_addr_from_round_as_json(request, round_id):
return helper_grants_output(request, meta_data, earnings)


def query_to_results(query):
with connection.cursor() as cursor:
cursor.execute(query)
rows = []
for _row in cursor.fetchall():
rows.append(list(_row))
return rows
return []

@login_required
@cached_view(timeout=3600)
def contribution_addr_from_all_as_json(request):
Expand All @@ -380,10 +406,8 @@ def contribution_addr_from_all_as_json(request):
'msg': f'not_authorized, check back at {grants_data_release_date.strftime("%Y-%m-%d")}'
}, safe=False)

_contributions = Contribution.objects.filter(
subscription__network='mainnet'
)
earnings = helper_contributions_to_earnings(_contributions)
query = f'select distinct contributor_address from grants_subscription where true {hide_wallet_address_anonymized_sql}'
earnings = query_to_results(query)
meta_data = {
}
return helper_grants_output(request, meta_data, earnings)
Expand Down
3 changes: 3 additions & 0 deletions app/kudos/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ def on_networks(self):
return_me.append((network, ref))
return return_me

@property
def on_other_networks(self):
return [ele for ele in self.on_networks if ele[0] != self.contract.network]

def on_network(self, network):
if self.contract.network == network:
Expand Down
6 changes: 3 additions & 3 deletions app/kudos/templates/kudos_details.html
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,12 @@ <h3 id="kudosName" class="kudos-details__title">{{ kudos.ui_name }} {% if kudos.
<div>
Network: {{kudos.contract.network}}

{% if kudos.on_networks|length %}
{% if kudos.on_other_networks|length %}
(Also available on
{% for other_kudos in kudos.on_networks %}
{% for other_kudos in kudos.on_other_networks %}
<a href="{{other_kudos.1.url}}">{{other_kudos.0}}</a>
)
{% endfor %}
)
{% endif %}
</div>
<div>Owner Address: <a target="_blank" href="https://etherscan.io/address/{{ kudos.owner_address }}" class="kudos-details__address" title="{{ kudos.owner_address }}">{{ kudos.owner_address|humanize_address }}</a></div>
Expand Down
5 changes: 3 additions & 2 deletions app/kudos/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,9 @@ def marketplace(request):
q = request.GET.get('q', '')
order_by = request.GET.get('order_by', '-created_on')
title = str(_('Kudos Marketplace'))
network = request.GET.get('network', settings.KUDOS_NETWORK)

network = request.GET.get('network', 'xdai')
if not network:
network = 'xdai'
# Only show the latest contract Kudos for the current network.
query_kwargs = {
'num_clones_allowed__gt': 0,
Expand Down
38 changes: 38 additions & 0 deletions app/marketing/management/commands/post_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,40 @@ def do_post(text, comment=None):
activity=activity,
comment=comment)

def quest():
from marketing.views import quest_of_the_day
quest = quest_of_the_day()
text = f"Quest of the Day: {quest.title}: {quest.url}"
print(text)

profile = Profile.objects.filter(handle='gitcoinbot').first()
metadata = {
'title': text,
'resource': {
'id': quest.enemy_img_url,
'type': "gif",
'provider': "giphy"
}
}
activity = Activity.objects.create(profile=profile, activity_type='status_update', metadata=metadata)

def kudos():
from marketing.views import kudos_of_the_day
kudos = kudos_of_the_day()
text = f"Kudos of the Day: {kudos.ui_name}: {kudos.url.replace('http://localhost:8000','https://gitcoin.co')}"
print(text)

profile = Profile.objects.filter(handle='gitcoinbot').first()
metadata = {
'title': text,
'resource': {
'id': kudos.img_url,
'type': "gif",
'provider': "giphy"
}
}
activity = Activity.objects.create(profile=profile, activity_type='status_update', metadata=metadata)

def quote():
quotes = [
[ ('Open source software has become a relevant part of the software industry and a number of software ecosystems. It has become an alternative to commercial software in various areas and is already included in many commercial software products.'), 'March 2017 Report by the EU' ],
Expand Down Expand Up @@ -493,6 +527,10 @@ def handle(self, *args, **options):
results()
elif options['what'] == 'quote':
quote()
elif options['what'] == 'quest':
quest()
elif options['what'] == 'kudos':
kudos()
elif options['what'] == 'earners':
earners()
elif options['what'] == 'grants':
Expand Down
10 changes: 10 additions & 0 deletions app/marketing/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,16 @@ def quest_of_the_day():
quest = trending_quests()[0] if (len(trending_quests())) else 0
return quest

def trending_kudos():
from kudos.models import KudosTransfer
cutoff_date = timezone.now() - timezone.timedelta(days=7)
kudos = [ele.kudos_token_cloned_from for ele in KudosTransfer.objects.order_by('?').all()[0:10]]
return kudos

def kudos_of_the_day():
quest = trending_kudos()[0] if (len(trending_quests())) else 0
return quest

def upcoming_grant():
grant = Grant.objects.order_by('-weighted_shuffle').first()
return grant
Expand Down
4 changes: 2 additions & 2 deletions app/retail/templates/results.html
Original file line number Diff line number Diff line change
Expand Up @@ -293,9 +293,9 @@ <h2 class="content-block__title">{{hackathons | length }} {% trans "Virtual Hack
{% for hackathon in hackathons %}
<div class="{% if forloop.counter > 7 %}hidden{%endif%}" >
{% if hackathon.1.logo %}
<img src="{{hackathon.1.logo}}"/>
<img data-src="{{hackathon.1.logo}}"/>
{%else %}
<img src="/dynamic/avatar/gitcoinbot"/>
<img data-src="/dynamic/avatar/gitcoinbot"/>
{%endif %}
<h4>{{hackathon.0.name}}</h4>
{% if hackathon.1.num_bounties and hackathon.1.total_volume > 1 %}
Expand Down
2 changes: 2 additions & 0 deletions docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* Get a list of contributors to a Gitcoin Grant at a specififc round `https://gitcoin.co/grants/v1/api/export_addresses/grantX_roundY.json` where X is the ID of the grant and Y is the round number. You must be authenticated as a team member of the grant to access the data.
* We've got an `https://gitcoin.co/grants/v1/api/export_addresses/all.json` endpoint available for those who'd like to just get all addresses that've ever funded a Gitcoin Grant.
* We've also put together a list of all grants on the platform, and the addresses you can contribute to them at, at https://gitcoin.co/grants/grants.json
* Get a list of contributor social info (handle, picture, anonymized, comment) for a Gitcoin Grant at a specific round `https://gitcoin.co/grants/v1/api/export_info/grantX_roundY.json` where X is the ID of the grant and Y is the round number. You must be authenticated as a team member of the grant to access the data.

These APIs are purposefully minimalistic, as we are trying very hard to limit the scope of the data retrieval methods in order to support narrow use cases..

Expand All @@ -17,6 +18,7 @@ Click through to try them below:
* https://gitcoin.co/grants/v1/api/export_addresses/grant12_round_7.json
* https://gitcoin.co/grants/v1/api/export_addresses/all.json
* https://gitcoin.co/grants/grants.json
* https://gitcoin.co/grants/v1/api/export_info/grant12_round_7.json

NOTE: Gitcoin respects user privacy, and gives users the option to opt out of including their addresses in these exports. Update your preferences at `https://gitcoin.co/settings/privacy` at anytime.

Expand Down
2 changes: 2 additions & 0 deletions scripts/crontab
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/us
15 10 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash funder_stale_email 60 >> /var/log/gitcoin/funder_stale_email.log 2>&1
15 5 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash new_bounties_email >> /var/log/gitcoin/new_bounties_email.log 2>&1
# 15 10 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash tribe_hackathon_prizes_email >> /var/log/gitcoin/tribe_hackathon_prizes_email.log 2>&1
30 5 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash post_data quest >> /var/log/gitcoin/post_data.log 2>&1
30 17 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash post_data kudos >> /var/log/gitcoin/post_data.log 2>&1
30 6 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash post_data grants >> /var/log/gitcoin/post_data.log 2>&1
15 15 * * 7 cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash post_data quote >> /var/log/gitcoin/post_data.log 2>&1
15 18 * * * cd gitcoin/coin; bash scripts/run_management_command_if_not_already_running.bash post_data results >> /var/log/gitcoin/post_data.log 2>&1
Expand Down

0 comments on commit 615b0f3

Please sign in to comment.