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)
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) maybe_market_tip_to_email(tip, emails) 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)
def handle(self, *args, **options): network = 'mainnet' if not settings.DEBUG else 'rinkeby' actually_send = not settings.DEBUG usernames = options['usernames'].split(",") _amount = options['amount'] DECIMALS = 18 from_address = settings.TIP_PAYOUT_ADDRESS from_pk = settings.TIP_PAYOUT_PRIVATE_KEY from_username = options['from_name'] DAI_ADDRESS = '0x6b175474e89094c44da98b954eedeac495271d0f' if network == 'mainnet' else '0x6a6e8b58dee0ca4b4ee147ad72d3ddd2ef1bf6f7' token_name = 'DAI' # https://gitcoin.co/_administrationperftools/jsonstore/1801078/change/ sybil_attack_addresses = JSONStore.objects.get( key='sybil_attack_addresses').data # payout rankings (round must be finalized first) TOKEN_ADDRESS = DAI_ADDRESS from_profile = Profile.objects.filter( handle=from_username.lower()).first() if not from_profile: print('no from_profile found') return sent_addresses = [] for username in usernames: # issue payment print(f"- issuing payout to {username}") profile = Profile.objects.filter(handle=username.lower()).first() if not profile: print('no profile found') continue if not profile.preferred_payout_address: print('no profile preferred_payout_address found') continue address = profile.preferred_payout_address w3 = get_web3(network) contract = w3.eth.contract(Web3.toChecksumAddress(TOKEN_ADDRESS), abi=abi) address = Web3.toChecksumAddress(address) amount = int(_amount * 10**DECIMALS) tx_id = '0x0' if actually_send: if address.lower() in sent_addresses: print( 'address was already in the sent addresess; skipping due to anti-sybil protections' ) continue if address.lower() in sybil_attack_addresses: print('skipping due to anti-sybil protections') continue sent_addresses.append(address.lower()) tx = contract.functions.transfer( address, amount ).buildTransaction({ 'nonce': w3.eth.getTransactionCount(from_address), 'gas': 60000, 'gasPrice': int( float(recommend_min_gas_price_to_confirm_in_time(1)) * 10**9 * 1.4) }) signed = w3.eth.account.signTransaction(tx, from_pk) tx_id = w3.eth.sendRawTransaction(signed.rawTransaction).hex() if not tx_id: print("cannot pay, did not get a txid") continue print("paid via", tx_id) # wait for tx to clear while not has_tx_mined(tx_id, network): time.sleep(1) metadata = { 'direct_address': profile.preferred_payout_address, 'creation_time': timezone.now().strftime("%Y-%m-%dT%H:00:00"), } # create objects tip = Tip.objects.create( primary_email=profile.email, emails=[profile.email], tokenName='DAI', amount=amount / 10**DECIMALS, comments_priv=options['comments_priv'], comments_public=options['comments_public'], ip="0.0.0.0", expires_date=timezone.now() + timezone.timedelta(days=10), github_url='', from_name=from_username, from_email=from_profile.email, from_username=from_username, username=profile.handle, network=network, tokenAddress=TOKEN_ADDRESS, from_address=from_address, is_for_bounty_fulfiller=False, metadata=metadata, recipient_profile=profile, sender_profile=from_profile, tx_status='pending', txid=tx_id, receive_tx_status='pending', receive_txid=tx_id, receive_address=profile.preferred_payout_address, tx_time=timezone.now(), receive_tx_time=timezone.now(), received_on=timezone.now(), ) tip.trigger_townsquare() 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) TipPayout.objects.create( txid=tx_id, profile=profile, tip=tip, ) print("SLEEPING") time.sleep(WAIT_TIME_BETWEEN_PAYOUTS) print("DONE SLEEPING")
def assign_tip_to(tip, handle): tip.username = handle tip.emails = get_emails_master(handle) maybe_market_tip_to_email(tip, tip.emails) tip.metadata['is_for_bounty_fulfiller_handled'] = True return tip
def send_tip_2(request): """Handle the second stage of sending a tip.""" username = request.session.get('handle') primary_email = request.session.get('email', '') if request.body: # http response response = { 'status': 'OK', 'message': 'Notification has been sent', } params = json.loads(request.body) username = username or params['username'] access_token = request.session.get('access_token') emails = get_github_emails(access_token) if access_token else [ primary_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=username, network=params['network'], tokenAddress=params['tokenAddress'], txid=params['txid'], ) # notifications maybe_market_tip_to_github(tip) maybe_market_tip_to_slack(tip, 'new_tip', tip.txid) maybe_market_tip_to_email(tip, emails) if not 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_email, 'from_handle': username } return TemplateResponse(request, 'yge/send2.html', params)