示例#1
0
 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}"
示例#2
0
    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)
示例#3
0
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'))
示例#4
0
    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)
示例#5
0
    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}"
示例#6
0
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
示例#7
0
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
示例#8
0
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
示例#9
0
    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)
示例#10
0
文件: embed.py 项目: protinam/web
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
示例#11
0
文件: embed.py 项目: protinam/web
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
示例#12
0
文件: embed.py 项目: sunxivincent/web
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
示例#13
0
 def github_org_name(self):
     try:
         return org_name(self.github_url)
     except Exception:
         return None
示例#14
0
 def org_name(self):
     try:
         _org_name = org_name(self.github_url)
         return _org_name
     except Exception:
         return None
示例#15
0
    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)
示例#16
0
 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'
示例#17
0
 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'