def price_in_usdt(self): from economy.utils import ConversionRateNotFoundError, convert_token_to_usdt if hasattr(self, 'price_usdt'): return self.price_usdt try: self.price_usdt = round(convert_token_to_usdt('ETH') * self.price_in_eth, 2) return self.price_usdt except ConversionRateNotFoundError: return None
def grants(): from grants.views import clr_active, clr_round if not clr_active: return ############################################################################3 # total stats ############################################################################3 start = next_round_start end = round_end day = (datetime.now() - start).days pprint("") pprint("================================") pprint(f"== BEEP BOOP BOP ⚡️ ") pprint( f"== Grants Round {clr_round} ({start.strftime('%m/%d/%Y')} ➡️ {end.strftime('%m/%d/%Y')})" ) pprint(f"== Day {day} Stats 💰🌲👇 ") pprint("================================") pprint("") must_be_successful = True contributions = Contribution.objects.filter(created_on__gt=start, created_on__lt=end) if must_be_successful: contributions = contributions.filter(success=True) pfs = PhantomFunding.objects.filter(created_on__gt=start, created_on__lt=end) total = contributions.count() + pfs.count() current_carts = CartActivity.objects.filter(latest=True) num_carts = 0 amount_in_carts = {} discount_cart_amounts_over_this_threshold_usdt_as_insincere_trolling = 1000 for ca in current_carts: for item in ca.metadata: currency, amount = item['grant_donation_currency'], item[ 'grant_donation_amount'] if currency not in amount_in_carts.keys(): amount_in_carts[currency] = [0, 0] if amount: usdt_amount = 0 try: usdt_amount = convert_token_to_usdt(currency) * float( amount) except Exception as e: pass if usdt_amount < discount_cart_amounts_over_this_threshold_usdt_as_insincere_trolling: amount_in_carts[currency][0] += float(amount) amount_in_carts[currency][1] += float(usdt_amount) contributors = len( set( list( contributions.values_list('subscription__contributor_profile', flat=True)) + list(pfs.values_list('profile', flat=True)))) amount = sum([ float(contrib.subscription.amount_per_period_usdt) for contrib in contributions ] + [float(pf.value) for pf in pfs]) pprint(f"Contributions: {total}") pprint(f"Contributors: {contributors}") pprint(f'Amount Raised: ${round(amount, 2)}') total_usdt_in_carts = 0 for key, val in amount_in_carts.items(): total_usdt_in_carts += val[1] pprint( f"{round(total_usdt_in_carts/1000, 1)}k DAI-equivilent in carts, but not yet checked out yet:" ) for key, val in amount_in_carts.items(): pprint(f"- {round(val[0], 2)} {key} (worth {round(val[1], 2)} DAI)") ############################################################################3 # top contributors ############################################################################3 all_contributors_by_amount = {} all_contributors_by_num = {} all_contributions_by_token = {} for contrib in contributions: key = contrib.subscription.contributor_profile.handle if key not in all_contributors_by_amount.keys(): all_contributors_by_amount[key] = 0 all_contributors_by_num[key] = 0 all_contributors_by_num[key] += 1 all_contributors_by_amount[ key] += contrib.subscription.amount_per_period_usdt key = contrib.subscription.token_symbol if key not in all_contributions_by_token.keys(): all_contributions_by_token[key] = 0 all_contributions_by_token[ key] += contrib.subscription.amount_per_period_usdt all_contributors_by_num = sorted(all_contributors_by_num.items(), key=operator.itemgetter(1)) all_contributors_by_num.reverse() all_contributors_by_amount = sorted(all_contributors_by_amount.items(), key=operator.itemgetter(1)) all_contributors_by_amount.reverse() all_contributions_by_token = sorted(all_contributions_by_token.items(), key=operator.itemgetter(1)) all_contributions_by_token.reverse() pprint("") pprint("=======================") pprint("") limit = 25 pprint(f"Top Contributors by Num Contributions (Round {clr_round})") counter = 0 for obj in all_contributors_by_num[0:limit]: counter += 1 pprint(f"{counter} - {str(round(obj[1]))} by @{obj[0]}") pprint("") pprint("=======================") pprint("") counter = 0 pprint(f"Top Contributors by Amount of Contributions (Round {clr_round})") for obj in all_contributors_by_amount[0:limit]: counter += 1 pprint(f"{counter} - ${str(round(obj[1], 2))} by @{obj[0]}") pprint("") pprint("=======================") pprint("") counter = 0 pprint(f"Saturation by Token (Round {clr_round})") for obj in all_contributions_by_token[0:limit]: counter += 1 pprint(f"{counter} - ${str(round(obj[1], 2))} in {obj[0]}") pprint("") pprint("=======================") pprint("") active_rounds = ['tech', 'media', 'change'] from grants.clr import TOTAL_POT_TECH, TOTAL_POT_MEDIA, TOTAL_POT_CHANGE active_round_threshold = { 'tech': TOTAL_POT_TECH, 'media': TOTAL_POT_MEDIA, 'change': TOTAL_POT_CHANGE, } active_rounds_allocation = {key: 0 for key in active_rounds} for ar in active_rounds: grants = Grant.objects.filter(active=True, grant_type=ar, is_clr_eligible=True, hidden=False) for grant in grants: try: active_rounds_allocation[ar] += grant.clr_prediction_curve[0][ 1] except: pass counter = 0 pprint( f"Total Saturation of Matching Funds By Round Type (Round {clr_round})" ) for key, val in active_rounds_allocation.items(): counter += 1 allocation_target = active_round_threshold[key] allocation_pct = round(100 * val / allocation_target) if key == 'media': key = 'community' #hack pprint( f"{counter} {key} - ${round(val, 2)} ({allocation_pct}% allocated)" ) ############################################################################3 # new feature stats for round {clr_round} ############################################################################3 subs_stats = False if subs_stats: subs = Subscription.objects.filter(created_on__gt=timezone.now() - timezone.timedelta(hours=48)) subs = subs.filter(subscription_contribution__success=True) pprint(subs.count()) pprint(subs.filter(num_tx_approved__gt=1).count()) pprint(subs.filter(is_postive_vote=False).count()) ############################################################################3 # all contributions export ############################################################################3 start = next_round_start end = round_end export = False if export: contributions = Contribution.objects.filter( created_on__gt=start, created_on__lt=end, success=True, subscription__network='mainnet')[0:100] pprint( "tx_id1, tx_id2, from address, amount, amount_minus_gitcoin, token_address" ) for contribution in contributions: pprint(contribution.tx_id, contribution.split_tx_id, contribution.subscription.contributor_address, contribution.subscription.amount_per_period, contribution.subscription.amount_per_period_minus_gas_price, contribution.subscription.token_address) pprint("") pprint("=======================") pprint("More @") pprint("⌗ https://gitcoin.co/grants/activity/") pprint("⌗ https://gitcoin.co/grants/stats/") pprint("=======================") global text do_post(text)
def grants(): active_clr_rounds = GrantCLR.objects.filter(is_active=True) if not active_clr_rounds.exists(): return ############################################################################3 # total stats ############################################################################3 start = active_clr_rounds.first().start_date end = active_clr_rounds.first().end_date day = (timezone.now() - start).days pprint("") pprint("================================") pprint(f"== BEEP BOOP BOP ⚡� ") pprint( f"== Grants Round ({start.strftime('%m/%d/%Y')} ➡� {end.strftime('%m/%d/%Y')})" ) pprint(f"== Day {day} Stats 💰🌲👇 ") pprint("================================") pprint("") must_be_successful = True contributions = Contribution.objects.filter(created_on__gt=start, created_on__lt=end) if must_be_successful: contributions = contributions.filter(success=True) pfs = PhantomFunding.objects.filter(created_on__gt=start, created_on__lt=end) total = contributions.count() + pfs.count() current_carts = CartActivity.objects.filter(latest=True) num_carts = 0 amount_in_carts = {} discount_cart_amounts_over_this_threshold_usdt_as_insincere_trolling = 1000 for ca in current_carts: for item in ca.metadata: currency, amount = item['grant_donation_currency'], item[ 'grant_donation_amount'] if currency not in amount_in_carts.keys(): amount_in_carts[currency] = [0, 0] if amount: usdt_amount = 0 try: usdt_amount = convert_token_to_usdt(currency) * float( amount) except Exception as e: pass if usdt_amount < discount_cart_amounts_over_this_threshold_usdt_as_insincere_trolling: try: amount_in_carts[currency][0] += float(amount) amount_in_carts[currency][1] += float(usdt_amount) except: pass contributors = len( set( list( contributions.values_list('subscription__contributor_profile', flat=True)) + list(pfs.values_list('profile', flat=True)))) amount = sum([ float(contrib.subscription.amount_per_period_usdt) for contrib in contributions ] + [float(pf.value) for pf in pfs]) pprint(f"Contributions: {total}") pprint(f"Contributors: {contributors}") pprint(f'Amount Raised: ${round(amount, 2)}') total_usdt_in_carts = 0 for key, val in amount_in_carts.items(): total_usdt_in_carts += val[1] pprint( f"{round(total_usdt_in_carts/1000, 1)}k DAI-equivilent in carts, but not yet checked out yet:" ) for key, val in amount_in_carts.items(): if val[1] > 10 and key: pprint( f"- {round(val[0], 2)} {key} (worth {round(val[1], 2)} DAI)") ############################################################################3 # top contributors ############################################################################3 all_contributors_by_amount = {} all_contributors_by_num = {} all_contributions_by_token = {} for contrib in contributions: key = contrib.subscription.contributor_profile.handle if key not in all_contributors_by_amount.keys(): all_contributors_by_amount[key] = 0 all_contributors_by_num[key] = 0 all_contributors_by_num[key] += 1 all_contributors_by_amount[ key] += contrib.subscription.amount_per_period_usdt key = contrib.subscription.token_symbol if key not in all_contributions_by_token.keys(): all_contributions_by_token[key] = 0 all_contributions_by_token[ key] += contrib.subscription.amount_per_period_usdt all_contributors_by_num = sorted(all_contributors_by_num.items(), key=operator.itemgetter(1)) all_contributors_by_num.reverse() all_contributors_by_amount = sorted(all_contributors_by_amount.items(), key=operator.itemgetter(1)) all_contributors_by_amount.reverse() all_contributions_by_token = sorted(all_contributions_by_token.items(), key=operator.itemgetter(1)) all_contributions_by_token.reverse() pprint("") pprint("=======================") pprint("") limit = 10 pprint(f"Top Contributors by Num Contributions") counter = 0 for obj in all_contributors_by_num[0:limit]: counter += 1 pprint(f"{counter} - {str(round(obj[1]))} by @{obj[0]}") pprint("") pprint("=======================") pprint("") counter = 0 pprint(f"Top Contributors by Amount of Contributions") for obj in all_contributors_by_amount[0:limit]: counter += 1 pprint(f"{counter} - ${str(round(obj[1], 2))} by @{obj[0]}") pprint("") pprint("=======================") pprint("") counter = 0 pprint(f"Saturation by Token") for obj in all_contributions_by_token[0:limit]: counter += 1 pprint(f"{counter} - ${str(round(obj[1], 2))} in {obj[0]}") pprint("") pprint("=======================") pprint("") active_rounds = [] active_round_threshold = {} active_rounds_allocation = {} for active_clr_round in active_clr_rounds: key = active_clr_round.round_num active_round_threshold[key] = float(active_clr_round.total_pot) active_rounds_allocation[key] = 0 active_rounds.append(key) grants = active_clr_round.grants.filter(active=True, is_clr_eligible=True, hidden=False) for grant in grants: try: active_rounds_allocation[key] += float( grant.clr_prediction_curve[0][1]) except Exception as e: print(e) counter = 0 pprint( f"Total Saturation of Matching Funds By Round Type (Round {clr_round})" ) for key, val in active_rounds_allocation.items(): counter += 1 allocation_target = active_round_threshold[key] allocation_pct = round(100 * val / allocation_target) if key == 'media': key = 'community' #hack pprint( f"{counter} {key} - ${round(val, 2)} ({allocation_pct}% allocated)" ) pprint("") pprint("=======================") pprint("") pprint("Misc Stats:") brightid_contributor_count = contributions.filter( subscription__contributor_profile__is_brightid_verified=True).distinct( 'subscription__contributor_profile').count() sms_contributor_count = contributions.filter( subscription__contributor_profile__sms_verification=True).distinct( 'subscription__contributor_profile').count() contributor_count = contributions.distinct( 'subscription__contributor_profile').count() sms_contributor_pct = round(100 * sms_contributor_count / contributor_count) brightid_contributor_pct = round(100 * brightid_contributor_count / contributor_count) zksync_contribution_count = contributions.filter( validator_comment__icontains='zkSync').count() contribution_count = contributions.count() zksync_contribution_pct = round(100 * zksync_contribution_count / contribution_count) sms_contribution_pct = round(100 * sms_contributor_count / contribution_count) pprint( f"- {zksync_contribution_count} ZkSync Contributions/{contribution_count} Total Contributions ({zksync_contribution_pct}%) " ) pprint( f"- {brightid_contributor_count} BrightID Verified Contributors/{contributor_count} Total Contributors ({brightid_contributor_pct}%) " ) pprint( f"- {sms_contributor_count} SMS Verified Contributors/{contributor_count} Total Contributors ({sms_contributor_pct}%) " ) ############################################################################3 # new feature stats for round {clr_round} ############################################################################3 subs_stats = False if subs_stats: subs = Subscription.objects.filter(created_on__gt=timezone.now() - timezone.timedelta(hours=48)) subs = subs.filter(subscription_contribution__success=True) pprint(subs.count()) pprint(subs.filter(num_tx_approved__gt=1).count()) pprint(subs.filter(is_postive_vote=False).count()) ############################################################################3 # all contributions export ############################################################################3 export = False if export: contributions = Contribution.objects.filter( created_on__gt=start, created_on__lt=end, success=True, subscription__network='mainnet')[0:100] pprint( "tx_id1, tx_id2, from address, amount, amount_minus_gitcoin, token_address" ) for contribution in contributions: print(contribution.tx_id, contribution.split_tx_id, contribution.subscription.contributor_address, contribution.subscription.amount_per_period, contribution.subscription.amount_per_period_minus_gas_price, contribution.subscription.token_address) pprint("") pprint("=======================") pprint("More @") pprint("⌗ https://gitcoin.co/grants/activity/") pprint("⌗ https://gitcoin.co/grants/stats/") pprint("=======================") global text do_post(text)
#created_on = timezone.datetime(2020, 6, 15, 8, 0) profile = Profile.objects.get(handle=handle) symbol = token value = 1.68 decimals = 18 value_adjusted = int(value / 10**int(decimals)) to = to_address grant = Grant.objects.filter(admin_address__iexact=to).order_by( '-positive_round_contributor_count').first() #ingest data currency = symbol amount = value usd_val = amount * convert_token_to_usdt(symbol) # convert formats date = timezone.now() # create objects validator_comment = f"created by ingest grant txn script" subscription = Subscription() subscription.is_postive_vote = True subscription.active = False subscription.error = True subscription.contributor_address = '/NA' subscription.amount_per_period = amount subscription.real_period_seconds = 2592000 subscription.frequency = 30 subscription.frequency_unit = 'N/A'
def token_value_in_usdt_then(self): try: return round( convert_token_to_usdt(self.tokenName, self.created_on), 2) except ConversionRateNotFoundError: return None
def token_value_in_usdt_now(self): try: return round(convert_token_to_usdt(self.tokenName), 2) except ConversionRateNotFoundError: return None
def token_value_in_usdt(self): return round(convert_token_to_usdt(self.token_name), 2)
def save_data(self, profile, txid, network, created_on, symbol, value_adjusted, grant, checkout_type): """ Creates contribution and subscription and saves it to database if no matching one exists """ currency = symbol amount = value_adjusted usd_val = amount * convert_token_to_usdt(symbol) # Check that subscription with these parameters does not exist existing_subscriptions = Subscription.objects.filter( grant__pk=grant.pk, contributor_profile=profile, split_tx_id=txid, token_symbol=currency ) for existing_subscription in existing_subscriptions: tolerance = 0.01 # 1% tolerance to account for floating point amount_max = amount * (1 + tolerance) amount_min = amount * (1 - tolerance) if ( existing_subscription.amount_per_period_minus_gas_price > amount_min and existing_subscription.amount_per_period_minus_gas_price < amount_max ): # Subscription exists print("Subscription exists, exiting function\n") return # No subscription found, so create subscription and contribution try: # create objects validator_comment = f"created by ingest grant txn script" subscription = Subscription() subscription.is_postive_vote = True subscription.active = False subscription.error = True subscription.contributor_address = "N/A" subscription.amount_per_period = amount subscription.real_period_seconds = 2592000 subscription.frequency = 30 subscription.frequency_unit = "N/A" subscription.token_address = "0x0" subscription.token_symbol = currency subscription.gas_price = 0 subscription.new_approve_tx_id = "0x0" subscription.num_tx_approved = 1 subscription.network = network subscription.contributor_profile = profile subscription.grant = grant subscription.comments = validator_comment subscription.amount_per_period_usdt = usd_val subscription.created_on = created_on subscription.last_contribution_date = created_on subscription.next_contribution_date = created_on subscription.split_tx_id = txid subscription.save() # Create contribution and set the contribution as successful contrib = subscription.successful_contribution( '0x0', # subscription.new_approve_tx_id, True, # include_for_clr checkout_type=checkout_type ) contrib.success=True contrib.tx_cleared=True contrib.tx_override=True contrib.validator_comment = validator_comment contrib.created_on = created_on contrib.save() print(f"ingested {subscription.pk} / {contrib.pk}") metadata = { "id": subscription.id, "value_in_token": str(subscription.amount_per_period), "value_in_usdt_now": str(round(subscription.amount_per_period_usdt, 2)), "token_name": subscription.token_symbol, "title": subscription.grant.title, "grant_url": subscription.grant.url, "num_tx_approved": subscription.num_tx_approved, "category": "grant", } kwargs = { "profile": profile, "subscription": subscription, "grant": subscription.grant, "activity_type": "new_grant_contribution", "metadata": metadata, } Activity.objects.create(**kwargs) print("Saved!\n") except Exception as e: print(e) print("\n")