def github_url(self): """Return the Github repository URL.""" if "https://github.com" not in self.action_url: raise Exception("not a github url") _repo_name = repo_name(self.action_url) _org_name = org_name(self.action_url) return f"https://github.com/{_org_name}/{_repo_name}"
def handle(self, *args, **options): notifications = get_notifications() print(len(notifications)) for notification in notifications: process_me = notification['reason'] == 'mention' if process_me: try: url = notification['subject']['url'] url = url.replace('/repos', '') url = url.replace('//api.github', '//github') latest_comment_url = notification['subject']['latest_comment_url'] _org_name = org_name(url) _repo_name = repo_name(url) _issue_number = issue_number(url) _comment_id = latest_comment_url.split('/')[-1] comment = get_issue_comments(_org_name, _repo_name, _issue_number, _comment_id) does_mention_gitcoinbot = settings.GITHUB_API_USER in comment.get('body','') if comment.get('message','') == "Not Found": print("comment was not found") elif not does_mention_gitcoinbot: print("does not mention gitcoinbot") else: comment_from = comment['user']['login'] num_reactions = comment['reactions']['total_count'] print(_org_name, _repo_name, _issue_number, _comment_id, num_reactions, comment_from) is_from_gitcoinbot = settings.GITHUB_API_USER in comment_from if num_reactions == 0 and not is_from_gitcoinbot: print("unprocessed") post_issue_comment_reaction(_org_name, _repo_name, _comment_id, 'heart') comment = f"@{comment_from}. :wave: thanks for the atMention, but you need to [install @gitcoinbot on this repo for me to be able to respond](https://github.com/apps/gitcoinbot). More details [in the documentation](https://github.com/gitcoinco/web/tree/master/app/gitcoinbot).\n\n:v:\n@gitcoinbot" post_issue_comment(_org_name, _repo_name, _issue_number, comment) except Exception as e: logging.exception(e) print(e)
def handle_avatar(request, _org_name='', add_gitcoincologo=False): from dashboard.models import Profile icon_size = (215, 215) if _org_name: try: profile = Profile.objects.select_related('avatar').get( handle__iexact=_org_name) if profile.avatar: if profile.avatar.use_github_avatar and profile.avatar.png: return HttpResponse(profile.avatar.png.file, content_type='image/png') elif profile.avatar.svg and not profile.avatar.use_github_avatar: return HttpResponse(profile.avatar.svg.file, content_type='image/svg+xml') except Exception as e: logger.error(e) # default response # params repo_url = request.GET.get('repo', False) if not _org_name and (not repo_url or 'github.com' not in repo_url): return get_err_response(request, blank_img=(_org_name == 'Self')) try: # get avatar of repo if not _org_name: _org_name = org_name(repo_url) filepath = get_avatar(_org_name) # new image img = Image.new('RGBA', icon_size, (255, 255, 255)) # execute avatar = Image.open(filepath, 'r').convert("RGBA") avatar = ImageOps.fit(avatar, icon_size, Image.ANTIALIAS) offset = 0, 0 img.paste(avatar, offset, avatar) # Determine if we should add the Gitcoin logo if add_gitcoincologo and _org_name != 'gitcoinco': img = add_gitcoin_logo_blend(avatar, icon_size) response = HttpResponse(content_type='image/png') img.save(response, 'PNG') return response except (AttributeError, IOError, SyntaxError) as e: logger.error(e) return get_err_response(request, blank_img=(_org_name == 'Self'))
def handle(self, *args, **options): num_days_back_to_warn = 3 num_days_back_to_delete_interest = 7 days = [i * 3 for i in range(1, 15)] if settings.DEBUG: days = range(1, 1000) for day in days: interests = Interest.objects.filter( created__gte=(timezone.now() - timezone.timedelta(days=(day+1))), created__lt=(timezone.now() - timezone.timedelta(days=day)), ).all() print('day {} got {} interests'.format(day, interests.count())) for interest in interests: for bounty in Bounty.objects.filter(interested=interest, current_bounty=True, idx_status__in=['open', 'started', 'submitted']): print("{} is interested in {}".format(interest, bounty)) try: owner = org_name(bounty.github_url) repo = repo_name(bounty.github_url) issue_num = issue_number(bounty.github_url) comments = get_issue_comments(owner, repo, issue_num) comments_by_interested_party = [comment for comment in comments if comment['user']['login'] == interest.profile.handle] should_warn_user = False should_delete_interest = False last_heard_from_user_days = None if len(comments_by_interested_party) == 0: should_warn_user = True should_delete_interest = False else: # example format: 2018-01-26T17:56:31Z' time_format = '%Y-%m-%dT%H:%M:%SZ' last_comment_by_user = datetime.strptime(comments_by_interested_party[0]['created_at'], time_format) delta_now_vs_last_comment = datetime.now() - last_comment_by_user last_heard_from_user_days = delta_now_vs_last_comment.days should_warn_user = last_heard_from_user_days >= num_days_back_to_warn should_delete_interest = last_heard_from_user_days >= num_days_back_to_delete_interest if should_delete_interest: print('executing should_delete_interest for {}'.format(interest.pk)) bounty_startwork_expired(interest.profile.email, bounty, interest, last_heard_from_user_days) interest.delete() elif should_warn_user: print('executing should_warn_user for {}'.format(interest.pk)) bounty_startwork_expire_warning(interest.profile.email, bounty, interest, last_heard_from_user_days) except Exception as e: print(e)
def get_relative_url(self, preceding_slash=True): """Get the relative URL for the Bounty. Attributes: preceding_slash (bool): Whether or not to include a preceding slash. Returns: str: The relative URL for the Bounty. """ try: _org_name = org_name(self.github_url) _issue_num = int(issue_number(self.github_url)) _repo_name = repo_name(self.github_url) return f"{'/' if preceding_slash else ''}issue/{_org_name}/{_repo_name}/{_issue_num}" except Exception: return f"{'/' if preceding_slash else ''}funding/details?url={self.github_url}"
def maybe_market_to_user_discord(bounty, event_name): """Send a Discord message to the user's discord channel for the specified Bounty. Args: bounty (dashboard.models.Bounty): The Bounty to be marketed. event_name (str): The name of the event. Returns: bool: Whether or not the Discord notification was sent successfully. """ from dashboard.models import Profile if bounty.get_natural_value() < 0.0001: return False if bounty.network != settings.ENABLE_NOTIFICATIONS_ON_NETWORK: return False msg = build_message_for_integration(bounty, event_name) if not msg: return False url = bounty.github_url sent = False try: repo = org_name(url) + '/' + repo_name(url) subscribers = Profile.objects.filter(discord_repos__contains=[repo]) subscribers = subscribers & Profile.objects.exclude( discord_webhook_url='') for subscriber in subscribers: try: headers = {'Content-Type': 'application/json'} body = { "content": msg, "avatar_url": "https://gitcoin.co/static/v2/images/helmet.png" } discord_response = requests.post( subscriber.discord_webhook_url, headers=headers, json=body) if discord_response.status_code == 204: sent = True except Exception as e: print(e) except Exception as e: print(e) return sent
def maybe_market_to_user_slack(bounty, event_name): """Send a Slack message to the user's slack channel for the specified Bounty. Args: bounty (dashboard.models.Bounty): The Bounty to be marketed. event_name (str): The name of the event. Returns: bool: Whether or not the Slack notification was sent successfully. """ from dashboard.models import Profile if bounty.get_natural_value() < 0.0001: return False if bounty.network != settings.ENABLE_NOTIFICATIONS_ON_NETWORK: return False msg = build_message_for_slack(bounty, event_name) if not msg: return False url = bounty.github_url sent = False try: repo = org_name(url) + '/' + repo_name(url) subscribers = Profile.objects.filter(slack_repos__contains=[repo]) subscribers = subscribers & Profile.objects.exclude(slack_token='', slack_channel='') for subscriber in subscribers: try: sc = SlackClient(subscriber.slack_token) sc.api_call( "chat.postMessage", channel=subscriber.slack_channel, text=msg, icon_url=settings.GITCOIN_SLACK_ICON_URL, ) sent = True except Exception as e: print(e) except Exception as e: print(e) return sent
def avatar(request, _org_name=None, add_gitcoincologo=None): # config icon_size = (215, 215) print(_org_name, add_gitcoincologo) # default response could_not_find = Image.new('RGBA', (1, 1), (0, 0, 0, 0)) err_response = HttpResponse(content_type="image/jpeg") could_not_find.save(err_response, "PNG") # params repo_url = request.GET.get('repo', False) if not _org_name and (not repo_url or 'github.com' not in repo_url): return err_response try: # get avatar of repo if not _org_name: _org_name = org_name(repo_url) filepath = get_avatar(_org_name) # new image img = Image.new("RGBA", icon_size, (255, 255, 255)) # execute avatar = Image.open(filepath, 'r').convert("RGBA") avatar = ImageOps.fit(avatar, icon_size, Image.ANTIALIAS) offset = 0, 0 img.paste(avatar, offset, avatar) # add gitcoinco logo? add_gitcoincologo = add_gitcoincologo and _org_name != 'gitcoinco' if add_gitcoincologo: img = add_gitcoin_logo_blend(avatar, icon_size) response = HttpResponse(content_type="image/png") img.save(response, "PNG") return response except IOError as e: print(e) return err_response except AttributeError as e: print(e) return err_response
def handle(self, *args, **options): notifications = get_notifications() print(len(notifications)) for notification in notifications: process_me = notification['reason'] == 'mention' if process_me: try: url = notification['subject']['url'] url = url.replace('/repos', '') url = url.replace('//api.github', '//github') latest_comment_url = notification['subject'][ 'latest_comment_url'] _org_name = org_name(url) _repo_name = repo_name(url) _issue_number = issue_number(url) _comment_id = latest_comment_url.split('/')[-1] comment = get_issue_comments(_org_name, _repo_name, _issue_number, _comment_id) does_mention_gitcoinbot = settings.GITHUB_API_USER in comment.get( 'body', '') if comment.get('message', '') == "Not Found": print("comment was not found") elif not does_mention_gitcoinbot: print("does not mention gitcoinbot") else: comment_from = comment['user']['login'] num_reactions = comment['reactions']['total_count'] print(_org_name, _repo_name, _issue_number, _comment_id, num_reactions, comment_from) is_from_gitcoinbot = settings.GITHUB_API_USER in comment_from if num_reactions == 0 and not is_from_gitcoinbot: print("unprocessed") post_issue_comment_reaction( _org_name, _repo_name, _comment_id, 'heart') except Exception as e: logging.exception(e) print(e)
def embed(request): # default response could_not_find = Image.new('RGBA', (1, 1), (0, 0, 0, 0)) err_response = HttpResponse(content_type="image/jpeg") could_not_find.save(err_response, "JPEG") # params repo_url = request.GET.get('repo', False) if not repo_url or 'github.com' not in repo_url: return err_response try: # get avatar of repo _org_name = org_name(repo_url) is_org_gitcoin = _org_name == 'gitcoinco' avatar = None filename = "{}.png".format(_org_name) filepath = 'assets/other/avatars/' + filename try: avatar = Image.open(filepath, 'r').convert("RGBA") except IOError: remote_user = get_user(_org_name) if not remote_user.get('avatar_url', False): return JsonResponse({'msg': 'invalid user'}, status=422) remote_avatar_url = remote_user['avatar_url'] r = requests.get(remote_avatar_url, stream=True) chunk_size = 20000 with open(filepath, 'wb') as fd: for chunk in r.iter_content(chunk_size): fd.write(chunk) avatar = Image.open(filepath, 'r').convert("RGBA") # make transparent datas = avatar.getdata() newData = [] for item in datas: if item[0] == 255 and item[1] == 255 and item[2] == 255: newData.append((255, 255, 255, 0)) else: newData.append(item) avatar.putdata(newData) avatar.save(filepath, "PNG") # get issues length = request.GET.get('len', 10) super_bounties = Bounty.objects.current().filter( github_url__startswith=repo_url, network='mainnet', idx_status='open').order_by('-_val_usd_db') bounties = super_bounties[:length] # config bounty_height = 145 bounty_width = 400 font_path = 'marketing/quotify/fonts/' width = 1350 height = 350 spacing = 0 line = "".join(["_" for ele in range(0, 47)]) # setup img = Image.new("RGBA", (width, height), (255, 255, 255)) black = (0, 0, 0) h1 = ImageFont.truetype(font_path + 'Futura-Bold.ttf', 28, encoding="unic") h2_thin = ImageFont.truetype(font_path + 'Futura-Normal.ttf', 22, encoding="unic") p = ImageFont.truetype(font_path + 'Futura-LightBT.ttf', 20, encoding="unic") # background ## config logo = 'assets/v2/images/header-bg-light.jpg' ## execute back = Image.open(logo, 'r').convert("RGBA") img_w, img_h = back.size bg_w, bg_h = img.size offset = 0, 0 img.paste(back, offset) # repo logo ## config icon_size = (215, 215) ## execute img_w, img_h = avatar.size avatar.thumbnail(icon_size, Image.ANTIALIAS) bg_w, bg_h = img.size offset = 10, 10 img.paste(avatar, offset, avatar) # gitcoin logo ## config logo = 'assets/v2/images/gitcoinco.png' ## execute back = Image.open(logo, 'r').convert("RGBA") back.thumbnail(icon_size, Image.ANTIALIAS) img_w, img_h = back.size bg_w, bg_h = img.size offset = 250, 10 if not is_org_gitcoin: img.paste(back, offset, back) # plus sign ## config if not is_org_gitcoin: text = '+' # execute text = wrap_text(text, 20) draw = ImageDraw.Draw(img) img_w, img_h = img.size x = 225 y = 60 draw.multiline_text(align="center", xy=(x, y), text=text, fill=black, font=h1, spacing=spacing) draw = ImageDraw.Draw(img) # header ## config text = '{} Supports Funded Issues'.format(_org_name.title()) # execute text = wrap_text(text, 30) draw = ImageDraw.Draw(img) img_w, img_h = img.size x = 10 y = 200 draw.multiline_text(align="left", xy=(x, y), text=text, fill=black, font=h1, spacing=spacing) draw = ImageDraw.Draw(img) ## config show_value, value = summarize_bounties(super_bounties) text = '{}\nPush Open Source Forward | Powered by Gitcoin.co'.format( wrap_text(value, 45) if show_value else "") # execute draw = ImageDraw.Draw(img) img_w, img_h = img.size x = 10 y = 225 draw.multiline_text(align="left", xy=(x, y), text=text, fill=black, font=h2_thin, spacing=12) draw = ImageDraw.Draw(img) # put bounty list in there i = 0 for bounty in bounties: i += 1 text = f"{line}\n{wrap_text(bounty.title_or_desc, 30)}\n\nWorth: " \ f"{round(bounty.value_true, 2)} {bounty.token_name} ({round(bounty.value_in_usdt, 2)} USD " \ f"@ ${round(convert_token_to_usdt(bounty.token_name), 2)}/{bounty.token_name})" # execute draw = ImageDraw.Draw(img) img_w, img_h = img.size line_size = 2 x = 500 + (int((i - 1) / line_size) * (bounty_width)) y = 30 + (abs(i % line_size - 1) * bounty_height) draw.multiline_text(align="left", xy=(x, y), text=text, fill=black, font=p, spacing=spacing) draw = ImageDraw.Draw(img) if bounties.count() == 0: text = "{}\n\n{}\n\n{}".format( line, wrap_text( "No active issues. Post a funded issue at https://gitcoin.co", 50), line) # execute draw = ImageDraw.Draw(img) img_w, img_h = img.size x = 10 y = 320 draw.multiline_text(align="left", xy=(x, y), text=text, fill=black, font=p, spacing=spacing) draw = ImageDraw.Draw(img) if bounties.count() != 0: ## config text = 'Browse Issues @ https://gitcoin.co/explorer' # execute text = wrap_text(text, 20) draw = ImageDraw.Draw(img) img_w, img_h = img.size x = 10 y = height - 50 draw.multiline_text(align="center", xy=(x, y), text=text, fill=black, font=h2_thin, spacing=spacing) draw = ImageDraw.Draw(img) response = HttpResponse(content_type="image/jpeg") img.save(response, "JPEG") return response except IOError as e: print(e) return err_response
def avatar(request): # default response could_not_find = Image.new('RGBA', (1, 1), (0, 0, 0, 0)) err_response = HttpResponse(content_type="image/jpeg") could_not_find.save(err_response, "JPEG") # params repo_url = request.GET.get('repo', False) if not repo_url or 'github.com' not in repo_url: return err_response try: # get avatar of repo _org_name = org_name(repo_url) avatar = None filename = "{}.png".format(_org_name) filepath = 'assets/other/avatars/' + filename try: avatar = Image.open(filepath, 'r').convert("RGBA") except IOError: remote_user = get_user(_org_name) if not remote_user.get('avatar_url', False): return JsonResponse({'msg': 'invalid user'}, status=422) remote_avatar_url = remote_user['avatar_url'] r = requests.get(remote_avatar_url, stream=True) chunk_size = 20000 with open(filepath, 'wb') as fd: for chunk in r.iter_content(chunk_size): fd.write(chunk) avatar = Image.open(filepath, 'r').convert("RGBA") # make transparent datas = avatar.getdata() newData = [] for item in datas: if item[0] == 255 and item[1] == 255 and item[2] == 255: newData.append((255, 255, 255, 0)) else: newData.append(item) avatar.putdata(newData) avatar.save(filepath, "PNG") width, height = (215, 215) img = Image.new("RGBA", (width, height), (255, 255, 255)) ## config icon_size = (215, 215) ## execute avatar = ImageOps.fit(avatar, icon_size, Image.ANTIALIAS) bg_w, bg_h = img.size offset = 0, 0 img.paste(avatar, offset, avatar) response = HttpResponse(content_type="image/jpeg") img.save(response, "JPEG") return response except IOError as e: print(e) return err_response
def embed(request): # default response could_not_find = Image.new('RGBA', (1, 1), (0, 0, 0, 0)) err_response = HttpResponse(content_type="image/jpeg") could_not_find.save(err_response, "JPEG") # params repo_url = request.GET.get('repo', False) if not repo_url or 'github.com' not in repo_url: return err_response try: # get avatar of repo _org_name = org_name(repo_url) avatar = None filename = f"{_org_name}.png" filepath = 'assets/other/avatars/' + filename try: avatar = Image.open(filepath, 'r').convert("RGBA") except IOError: remote_user = get_user(_org_name) if not remote_user.get('avatar_url', False): return JsonResponse({'msg': 'invalid user'}, status=422) remote_avatar_url = remote_user['avatar_url'] r = requests.get(remote_avatar_url, stream=True) chunk_size = 20000 with open(filepath, 'wb') as fd: for chunk in r.iter_content(chunk_size): fd.write(chunk) avatar = Image.open(filepath, 'r').convert("RGBA") # make transparent datas = avatar.getdata() new_data = [] for item in datas: if item[0] == 255 and item[1] == 255 and item[2] == 255: new_data.append((255, 255, 255, 0)) else: new_data.append(item) avatar.putdata(new_data) avatar.save(filepath, "PNG") # get issues length = request.GET.get('len', 10) super_bounties = Bounty.objects.current() \ .filter( github_url__startswith=repo_url, network='mainnet', idx_status__in=['open', 'started', 'submitted'] ).order_by('-_val_usd_db') bounties = super_bounties[:length] # config bounty_height = 200 bounty_width = 572 font = 'assets/v2/fonts/futura/FuturaStd-Medium.otf' width = 1776 height = 576 # setup img = Image.new("RGBA", (width, height), (255, 255, 255)) draw = ImageDraw.Draw(img) black = (0, 0, 0) gray = (102, 102, 102) h1 = ImageFont.truetype(font, 36, encoding="unic") h2_thin = ImageFont.truetype(font, 36, encoding="unic") p = ImageFont.truetype(font, 24, encoding="unic") # background background_image = 'assets/v2/images/embed-widget/background.png' back = Image.open(background_image, 'r').convert("RGBA") offset = 0, 0 img.paste(back, offset) # repo logo icon_size = (184, 184) avatar.thumbnail(icon_size, Image.ANTIALIAS) offset = 195, 148 img.paste(avatar, offset, avatar) img_org_name = ImageDraw.Draw(img) img_org_name_size = img_org_name.textsize(_org_name, h1) img_org_name.multiline_text( align="left", xy=(287 - img_org_name_size[0] / 2, 360), text=_org_name, fill=black, font=h1, ) draw.multiline_text( align="left", xy=(110, 410), text="supports funded issues", fill=black, font=h1, ) # put bounty list in there i = 0 for bounty in bounties[:4]: i += 1 # execute line_size = 2 # Limit text to 28 chars text = f"{bounty.title_or_desc}" text = (text[:28] + '...') if len(text) > 28 else text x = 620 + (int((i - 1) / line_size) * (bounty_width)) y = 230 + (abs(i % line_size - 1) * bounty_height) draw.multiline_text(align="left", xy=(x, y), text=text, fill=black, font=h2_thin) unit = 'day' num = int(round((bounty.expires_date - timezone.now()).days, 0)) if num == 0: unit = 'hour' num = int( round((bounty.expires_date - timezone.now()).seconds / 3600 / 24, 0)) unit = unit + ("s" if num != 1 else "") draw.multiline_text( align="left", xy=(x, y - 40), text=f"Expires in {num} {unit}:", fill=gray, font=p, ) bounty_eth_background = Image.new("RGBA", (200, 56), (231, 240, 250)) bounty_usd_background = Image.new("RGBA", (200, 56), (214, 251, 235)) img.paste(bounty_eth_background, (x, y + 50)) img.paste(bounty_usd_background, (x + 210, y + 50)) tmp = ImageDraw.Draw(img) bounty_value_size = tmp.textsize( f"{round(bounty.value_true, 2)} {bounty.token_name}", p) draw.multiline_text( align="left", xy=(x + 100 - bounty_value_size[0] / 2, y + 67), text=f"{round(bounty.value_true, 2)} {bounty.token_name}", fill=(44, 35, 169), font=p, ) bounty_value_size = tmp.textsize( f"{round(bounty.value_in_usdt_now, 2)} USD", p) draw.multiline_text( align="left", xy=(x + 310 - bounty_value_size[0] / 2, y + 67), text=f"{round(bounty.value_in_usdt_now, 2)} USD", fill=(45, 168, 116), font=p, ) # blank slate if bounties.count() == 0: draw.multiline_text( align="left", xy=(760, 320), text= "No active issues. Post a funded issue at: https://gitcoin.co", fill=gray, font=h1, ) if bounties.count() != 0: text = 'Browse issues at: https://gitcoin.co/explorer' draw.multiline_text( align="left", xy=(64, height - 70), text=text, fill=gray, font=p, ) draw.multiline_text( align="left", xy=(624, 120), text="Recently funded issues:", fill=(62, 36, 251), font=p, ) _, value = summarize_bounties(super_bounties) value_size = tmp.textsize(value, p) draw.multiline_text( align="left", xy=(1725 - value_size[0], 120), text=value, fill=gray, font=p, ) line_table_header = Image.new("RGBA", (1100, 6), (62, 36, 251)) img.paste(line_table_header, (624, 155)) # Resize back to output size for better anti-alias img = img.resize((888, 288), Image.LANCZOS) # Return image with right content-type response = HttpResponse(content_type="image/png") img.save(response, "PNG") return response except IOError as e: print(e) return err_response
def github_org_name(self): try: return org_name(self.github_url) except Exception: return None
def org_name(self): try: _org_name = org_name(self.github_url) return _org_name except Exception: return None
def handle(self, *args, **options): num_days_back_to_warn = 3 num_days_back_to_delete_interest = 7 days = [i * 3 for i in range(1, 15)] if settings.DEBUG: days = range(1, 1000) for day in days: interests = Interest.objects.filter( created__gte=(timezone.now() - timezone.timedelta(days=(day + 1))), created__lt=(timezone.now() - timezone.timedelta(days=day)), ).all() print('day {} got {} interests'.format(day, interests.count())) for interest in interests: for bounty in Bounty.objects.filter( interested=interest, current_bounty=True, idx_status__in=['open', 'started']): print("{} is interested in {}".format(interest, bounty)) try: owner = org_name(bounty.github_url) repo = repo_name(bounty.github_url) issue_num = issue_number(bounty.github_url) comments = get_issue_comments(owner, repo, issue_num) comments_by_interested_party = [ comment for comment in comments if comment['user'] ['login'] == interest.profile.handle ] should_warn_user = False should_delete_interest = False last_heard_from_user_days = None if len(comments_by_interested_party) == 0: should_warn_user = True should_delete_interest = False else: # example format: 2018-01-26T17:56:31Z' comment_times = [ datetime.strptime(comment['created_at'], '%Y-%m-%dT%H:%M:%SZ') for comment in comments_by_interested_party ] last_comment_by_user = max(comment_times) # if user hasn't commented since they expressed interest, handled this condition # per https://github.com/gitcoinco/web/issues/462#issuecomment-368384384 if last_comment_by_user < interest.created_at.replace( tzinfo=None): last_comment_by_user = interest.created_at.replace( tzinfo=None) # some small calcs delta_now_vs_last_comment = datetime.now( ) - last_comment_by_user last_heard_from_user_days = delta_now_vs_last_comment.days # decide action params should_warn_user = last_heard_from_user_days >= num_days_back_to_warn should_delete_interest = last_heard_from_user_days >= num_days_back_to_delete_interest print( f"- its been {last_heard_from_user_days} days since we heard from the user" ) if should_delete_interest: print('executing should_delete_interest for {}'. format(interest.pk)) bounty_startwork_expired( interest.profile.email, bounty, interest, last_heard_from_user_days) interest.delete() elif should_warn_user: print('executing should_warn_user for {}'.format( interest.pk)) bounty_startwork_expire_warning( interest.profile.email, bounty, interest, last_heard_from_user_days) except Exception as e: print(e)
def test_org_name(self): """Test the github utility org_name method.""" assert org_name( 'https://github.com/gitcoinco/web/issues/1') == 'gitcoinco' assert org_name( 'https://github.com/gitcoinco/web/issues/1/') == 'gitcoinco'
def test_org_name(self): """Test the github utility org_name method.""" assert org_name('https://github.com/gitcoinco/web/issues/1') == 'gitcoinco' assert org_name('https://github.com/gitcoinco/web/issues/1/') == 'gitcoinco'