Example #1
0
def github(update: Update, context: CallbackContext):
    message = update.message or update.edited_message
    last = 0
    thing_matches = []
    things = {}

    # Due to bug in ptb we need to convert entities of type URL to TEXT_LINK for them to be converted to html
    for entity in message.entities:
        if entity.type == MessageEntity.URL:
            entity.type = MessageEntity.TEXT_LINK
            entity.url = message.parse_entity(entity)

    for match in GITHUB_PATTERN.finditer(get_text_not_in_entities(message.text_html)):
        logging.debug(match.groupdict())
        owner, repo, number, sha = [match.groupdict()[x] for x in ('owner', 'repo', 'number', 'sha')]
        if number or sha:
            thing_matches.append((owner, repo, number, sha))

    for thing_match in thing_matches:
        last = keep_typing(last, update.effective_chat, ChatAction.TYPING)
        owner, repo, number, sha = thing_match
        if number:
            issue = github_issues.get_issue(int(number), owner, repo)
            things[issue.url] = github_issues.pretty_format_issue(issue)
        elif sha:
            commit = github_issues.get_commit(sha, owner, repo)
            things[commit.url] = github_issues.pretty_format_commit(commit)

    if things:
        reply_or_edit(update, context, '\n'.join([f'<a href="{url}">{name}</a>' for url, name in things.items()]))
Example #2
0
def github(update: Update, context: CallbackContext):
    message = update.message or update.edited_message
    last = 0
    thing_matches = []
    things = {}

    # Due to bug in ptb we need to convert entities of type URL to TEXT_LINK for them to be converted to html
    for entity in message.entities:
        if entity.type == MessageEntity.URL:
            entity.type = MessageEntity.TEXT_LINK
            entity.url = message.parse_entity(entity)

    for match in GITHUB_PATTERN.finditer(get_text_not_in_entities(message.text_html)):
        logging.debug(match.groupdict())
        owner, repo, number, sha = [match.groupdict()[x] for x in ('owner', 'repo', 'number', 'sha')]
        if number or sha:
            thing_matches.append((owner, repo, number, sha))

    for thing_match in thing_matches:
        last = keep_typing(last, update.effective_chat, ChatAction.TYPING)
        owner, repo, number, sha = thing_match
        if number:
            issue = github_issues.get_issue(int(number), owner, repo)
            things[issue.url] = github_issues.pretty_format_issue(issue)
        elif sha:
            commit = github_issues.get_commit(sha, owner, repo)
            things[commit.url] = github_issues.pretty_format_commit(commit)

    if things:
        reply_or_edit(update, context, '\n'.join([f'[{name}]({url})' for url, name in things.items()]))
Example #3
0
def github(bot, update, chat_data):
    message = update.message or update.edited_message
    last = 0
    things = {}


    for entity in message.entities:
        if entity.type == MessageEntity.URL:
            entity.type = MessageEntity.TEXT_LINK
            entity.url = message.parse_entity(entity)

    for match in GITHUB_PATTERN.finditer(get_text_not_in_entities(message.text_html)):
        last = keep_typing(last, update.effective_chat, ChatAction.TYPING)
        logging.debug(match.groupdict())

        owner, repo, number, sha = [match.groupdict()[x] for x in ('owner', 'repo', 'number', 'sha')]
        if number:
            issue = github_issues.get_issue(int(number), owner, repo)
            things[issue.url] = github_issues.pretty_format_issue(issue)
        elif sha:
            commit = github_issues.get_commit(sha, owner, repo)
            things[commit.url] = github_issues.pretty_format_commit(commit)

    if things:
        reply_or_edit(bot, update, chat_data,
                      '\n'.join([f'[{name}]({url})' for url, name in things.items()]))
Example #4
0
def github(bot, update, chat_data):
    message = update.message or update.edited_message
    last = 0
    things = {}

    # Due to bug in ptb we need to convert entities of type URL to TEXT_LINK for them to be converted to html
    for entity in message.entities:
        if entity.type == MessageEntity.URL:
            entity.type = MessageEntity.TEXT_LINK
            entity.url = message.parse_entity(entity)

    for match in GITHUB_PATTERN.finditer(
            get_text_not_in_entities(message.text_html)):
        last = keep_typing(last, update.effective_chat, ChatAction.TYPING)
        logging.debug(match.groupdict())

        user, repo, number, sha = [
            match.groupdict()[x] for x in ('user', 'repo', 'number', 'sha')
        ]
        url = GITHUB_URL
        name = ''
        if number:
            if user and repo:
                url += f'{user}/{repo}'
                name += f'{user}/{repo}'
            else:
                url += DEFAULT_REPO
            name += f'#{number}'
            url += f'/issues/{number}'
        else:
            if user:
                name += user
                if repo:
                    url += f'{user}/{repo}'
                    name += f'/{repo}'
                name += '@'
            if not repo:
                url += DEFAULT_REPO
            name += sha[:7]
            url += f'/commit/{sha}'

        if url in things.keys():
            continue

        gh = _get_github_title_and_type(url, sha)
        if not gh:
            continue

        name = f'{gh[1]} {name}: {gh[0]}'
        things[url] = name

    if things:
        reply_or_edit(
            bot, update, chat_data,
            '\n'.join([f'[{name}]({url})' for url, name in things.items()]))
Example #5
0
def inline_github(query):
    """
    Parse query for issues, PRs and commits SHA
    Returns a list of `articles`.

    Examples:
        `#10` - [(title=Replace via GitHub,
                 description=#10: tenth issue title)]
        `#10 #9` - [(title=Replace via GitHub,
                    description=#10: tenth issue title, #9: ninth issue)]
        `@d6d0dec6e0e8b647d140dfb74db66ecb1d00a61d` - [(title=Replace via GitHub,
                                                        description=@d6d0dec: commit title)]
        `#search` - [(title= 🔍 An issue with search in it's issue,
                      description=#3: that issue),
                     (title= 🔍 Another issue with search in it's issue,
                      description=#2: that issue),
                     ... (3 more)]
        `#10 #search` - [(title=An issue with search in it's issue,
                          description=#10: tenth issue, #3: that issue),
                         (title=Another issue with search in it's issue,
                          description=#10: tenth issue, #2: that issue),
                         ... (3 more)]
        `#search #10` - [(title= 🔍 An issue with search in it's issue,
                          description=#3: that issue, #10: tenth issue),
                         (title= 🔍 Another issue with search in it's issue,
                          description=#2: that issue, #10, tenth issue),
                         ... (3 more)]
        `#search1 #10 #search2` - [(title= 🔍 An issue with search2 in it's issue,
                                    description=#3: search1 result, #10: tenth issue, #5: search2 result1),
                                   (title= 🔍 Another issue with search2 in it's issue,
                                    description=#3: search1 result, #10, tenth issue, #6: search2 result2),
                                   ... (3 more)]
    """
    # Issues/PRs/Commits
    things = OrderedDict()
    results = []

    # Search for Issues, PRs and commits in the query and add them to things
    for match in GITHUB_PATTERN.finditer(query):
        owner, repo, number, sha, search_query, full = [
            match.groupdict()[x]
            for x in ('owner', 'repo', 'number', 'sha', 'query', 'full')
        ]
        # If it's an issue
        if number:
            issue = github_issues.get_issue(int(number), owner, repo)
            things[full] = issue
        # If it's a commit
        elif sha:
            commit = github_issues.get_commit(sha, owner, repo)
            things[full] = commit
        # If it's a search
        elif search_query:
            search_results = github_issues.search(search_query)
            things['#' + search_query] = search_results

    if not things:
        # We didn't find anything
        return []

    # Unwrap and collapse things
    last_search, choices = unwrap(things)

    # Loop over all the choices we should send to the client
    # Each choice (things) is a dict of things (issues/PRs/commits) to show in that choice
    # If not searching there will only be a single choice
    # If searching we have 5 different possibilities we wanna send
    for i, things in enumerate(choices):
        # If we did a search
        if last_search and last_search[i]:
            # Show the search title as the title
            title = '🔍' + github_issues.pretty_format(
                last_search[i], short_with_title=True, title_max_length=50)
        else:
            # Otherwise just use generic title
            title = 'Resolve via GitHub'

        # Description is the short formats combined with ', '
        description = (', '.join(
            github_issues.pretty_format(thing, short_with_title=True)
            for thing in things.values()))

        # Truncate the description to 100 chars, from the left side.
        # So the last thing will always be shown.
        if len(description) > 100:
            description = '⟻' + description[-99:].partition(',')[2]

        # The text that will be sent when user clicks the choice/result
        text = ''
        pattern = r'|'.join(
            re.escape(thing)
            for thing in sorted(things.keys(), key=len, reverse=True))
        # Check if there's other stuff than issues/PRs etc. in the query by
        # removing issues/PRs etc. and seeing if there's anything left
        if re.sub(pattern, '', query).strip():
            # Replace every 'thing' with a link to said thing *all at once*
            # Needs to all at once because otherwise 'blah/blah#2 #2'
            # would break would turn into something like
            # [blah/blah[#2](LinkFor#2)](LinkForblah/blah[#2](LinkFor#2))
            # which isn't even valid markdown
            text = re.sub(
                pattern, lambda x: f'<a href="{things[x.group(0)].url}">'
                f'{github_issues.pretty_format(things[x.group(0)], short=True)}</a>',
                query)

        # Add full format to bottom of message
        text += '\n\n' + '\n'.join(
            f'<a href="{thing.url}">{github_issues.pretty_format(thing)}</a>'
            for thing in things.values())

        results.append(
            article(title=title, description=description, message_text=text))

    return results
Example #6
0
def inline_github(query):
    """
    Parse query for issues, PRs and commits SHA
    Returns a list of `articles`.

    Examples:
        `#10` - [(title=Replace via GitHub,
                 description=#10: tenth issue title)]
        `#10 #9` - [(title=Replace via GitHub,
                    description=#10: tenth issue title, #9: ninth issue)]
        `@d6d0dec6e0e8b647d140dfb74db66ecb1d00a61d` - [(title=Replace via GitHub,
                                                        description=@d6d0dec: commit title)]
        `#search` - [(title= 🔍 An issue with search in it's issue,
                      description=#3: that issue),
                     (title= 🔍 Another issue with search in it's issue,
                      description=#2: that issue),
                     ... (3 more)]
        `#10 #search` - [(title=An issue with search in it's issue,
                          description=#10: tenth issue, #3: that issue),
                         (title=Another issue with search in it's issue,
                          description=#10: tenth issue, #2: that issue),
                         ... (3 more)]
        `#search #10` - [(title= 🔍 An issue with search in it's issue,
                          description=#3: that issue, #10: tenth issue),
                         (title= 🔍 Another issue with search in it's issue,
                          description=#2: that issue, #10, tenth issue),
                         ... (3 more)]
        `#search1 #10 #search2` - [(title= 🔍 An issue with search2 in it's issue,
                                    description=#3: search1 result, #10: tenth issue, #5: search2 result1),
                                   (title= 🔍 Another issue with search2 in it's issue,
                                    description=#3: search1 result, #10, tenth issue, #6: search2 result2),
                                   ... (3 more)]
    """
    # Issues/PRs/Commits
    things = OrderedDict()
    results = []

    # Search for Issues, PRs and commits in the query and add them to things
    for match in GITHUB_PATTERN.finditer(query):
        owner, repo, number, sha, search_query, full = [match.groupdict()[x] for x in ('owner', 'repo', 'number',
                                                                                       'sha', 'query', 'full')]
        # If it's an issue
        if number:
            issue = github_issues.get_issue(int(number), owner, repo)
            things[full] = issue
        # If it's a commit
        elif sha:
            commit = github_issues.get_commit(sha, owner, repo)
            things[full] = commit
        # If it's a search
        elif search_query:
            search_results = github_issues.search(search_query)
            things['#' + search_query] = search_results

    if not things:
        # We didn't find anything
        return []

    # Unwrap and collapse things
    last_search, choices = unwrap(things)

    # Loop over all the choices we should send to the client
    # Each choice (things) is a dict of things (issues/PRs/commits) to show in that choice
    # If not searching there will only be a single choice
    # If searching we have 5 different possibilities we wanna send
    for i, things in enumerate(choices):
        # If we did a search
        if last_search and last_search[i]:
            # Show the search title as the title
            title = '🔍' + github_issues.pretty_format(last_search[i],
                                                       short_with_title=True,
                                                       title_max_length=50)
        else:
            # Otherwise just use generic title
            title = 'Resolve via GitHub'

        # Description is the short formats combined with ', '
        description = (', '.join(github_issues.pretty_format(thing, short_with_title=True)
                                 for thing in things.values()))

        # Truncate the description to 100 chars, from the left side.
        # So the last thing will always be shown.
        if len(description) > 100:
            description = '⟻' + description[-99:].partition(',')[2]

        # The text that will be sent when user clicks the choice/result
        text = ''
        pattern = r'|'.join(re.escape(thing) for thing in sorted(things.keys(), key=len, reverse=True))
        # Check if there's other stuff than issues/PRs etc. in the query by
        # removing issues/PRs etc. and seeing if there's anything left
        if re.sub(pattern, '', query).strip():
            # Replace every 'thing' with a link to said thing *all at once*
            # Needs to all at once because otherwise 'blah/blah#2 #2'
            # would break would turn into something like
            # [blah/blah[#2](LinkFor#2)](LinkForblah/blah[#2](LinkFor#2))
            # which isn't even valid markdown
            text = re.sub(pattern,
                          lambda x: f'[{github_issues.pretty_format(things[x.group(0)], short=True)}]'
                          f'({things[x.group(0)].url})', query)

        # Add full format to bottom of message
        text += '\n\n' + '\n'.join(f'[{github_issues.pretty_format(thing)}]({thing.url})'
                                   for thing in things.values())

        results.append(article(title=title, description=description, message_text=text))

    return results