add pull request support (resolve #7)

This commit is contained in:
yanyongyu 2021-09-12 02:07:58 +08:00
parent fc137f09f2
commit 3a534e0652
7 changed files with 174 additions and 29 deletions

View File

@ -4,7 +4,7 @@
@Author : yanyongyu
@Date : 2021-03-11 01:34:31
@LastEditors : yanyongyu
@LastEditTime : 2021-06-15 22:11:43
@LastEditTime : 2021-09-12 01:56:57
@Description : None
@GitHub : https://github.com/yanyongyu
"""
@ -82,9 +82,8 @@ class PaginatedList(AsyncIterator, Generic[C]):
return current
def __aiter__(self) -> "PaginatedList[C]":
new_page = copy.deepcopy(self)
new_page._index = 0
return new_page
return PaginatedList(
self.cls, self.requester, *self.args, per_page=self.per_page, **self.kwargs)
async def _get_next_page(self) -> List[C]:
self._current_page += 1
@ -102,6 +101,8 @@ class PaginatedList(AsyncIterator, Generic[C]):
return content
from .repository import LazyRepository, Repository
from .issue import Issue
from .label import Label
from .license import License
@ -110,4 +111,3 @@ from .hook import Hook, HookConfig
from .timeline import TimelineEvent
from .permissions import Permissions
from .user import User, Organization
from .repository import LazyRepository, Repository

View File

@ -4,7 +4,7 @@
@Author : yanyongyu
@Date : 2021-03-11 16:57:04
@LastEditors : yanyongyu
@LastEditTime : 2021-08-20 23:52:12
@LastEditTime : 2021-09-12 01:20:35
@Description : None
@GitHub : https://github.com/yanyongyu
"""
@ -20,6 +20,7 @@ from . import BaseModel, PaginatedList
from .user import User
from .label import Label
from .comment import Comment
from .pull_request import PullRequest
from .timeline import (
TimelineEvent, TimelineEventCommited, TimelineEventForcePushed,
TimelineEventHeadDeleted, TimelineEventReferenced, TimelineEventCommented,
@ -118,15 +119,32 @@ class Issue(BaseModel):
self.timeline_url,
headers=headers)
async def get_pull_request(self) -> PullRequest:
"""
GET /repo/:full_name/pull/:number
"""
if not self.pull_request:
raise RuntimeError(f"Issue {self.number} is not a pull request")
headers = {
"Accept": "application/vnd.github.v3.full+json"
}
response = await self.requester.request(
"GET",
self.pull_request.url,
headers=headers
)
return PullRequest.parse_obj({"requester": self.requester, **response.json()})
async def get_diff(self) -> str:
"""
GET /repo/:full_name/pull/:number.diff
"""
if not self.is_pull_request:
if not self.pull_request:
raise RuntimeError(f"Issue {self.number} is not a pull request")
response = await self.requester.request(
"GET",
self.pull_request.diff_url # type: ignore
self.pull_request.diff_url
)
return response.text

View File

@ -0,0 +1,104 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
@Author : yanyongyu
@Date : 2021-09-12 00:35:57
@LastEditors : yanyongyu
@LastEditTime : 2021-09-12 01:47:10
@Description : None
@GitHub : https://github.com/yanyongyu
"""
__author__ = "yanyongyu"
from datetime import datetime
from typing import Any, List, Union, Optional
from pydantic import BaseModel as _BaseModel
from . import BaseModel
from .label import Label
from .user import User, Actor
from .repository import Repository
class PullRequestTeam(_BaseModel):
id: int
node_id: str
url: str
html_url: str
name: str
slug: str
description: str
privacy: str
permission: str
members_url: str
repositories_url: str
class PullRequestCommit(_BaseModel):
label: str
ref: str
sha: str
user: Actor
repo: Optional[Repository]
class PullRequest(BaseModel):
id: int
node_id: str
url: str
html_url: str
diff_url: str
patch_url: str
issue_url: str
number: int
state: str
locked: bool
title: str
user: User
body: Optional[str]
body_text: Optional[str]
body_html: Optional[str]
created_at: datetime
updated_at: datetime
closed_at: Optional[datetime]
merged_at: Optional[datetime]
merge_commit_sha: str
assignee: Optional[User]
assignees: List[User]
requested_reviewers: List[User]
requested_teams: List[PullRequestTeam]
labels: List[Label]
# milestone: Optional[Milestone]
draft: bool
commits_url: str
review_comments_url: str
review_comment_url: str
comments_url: str
statuses_url: str
head: PullRequestCommit
base: PullRequestCommit
author_association: str
# FIXME: what's this?
auto_merge: Optional[Any]
active_lock_reason: Optional[str]
merged: bool
mergeable: Optional[bool]
rebaseable: Optional[bool]
mergeable_state: str
merged_by: Optional[User]
comments: int
review_comments: int
maintainer_can_modify: bool
commits: int
additions: int
deletions: int
changed_files: int
async def get_diff(self) -> str:
response = await self.requester.request(
"GET",
self.diff_url
)
return response.text

View File

@ -4,7 +4,7 @@
@Author : yanyongyu
@Date : 2021-03-11 01:33:54
@LastEditors : yanyongyu
@LastEditTime : 2021-06-08 19:56:15
@LastEditTime : 2021-09-12 01:43:57
@Description : None
@GitHub : https://github.com/yanyongyu
"""
@ -16,7 +16,6 @@ from typing import List, Union, Optional
from . import BaseModel
from .issue import Issue
from .license import License
from .hook import Hook, HookConfig
from .user import User, Organization
@ -26,7 +25,7 @@ from .permissions import Permissions
class LazyRepository(BaseModel):
full_name: str
async def get_issue(self, number: int) -> Issue:
async def get_issue(self, number: int) -> "Issue":
"""
GET /repo/:full_name/issues/:number
@ -216,3 +215,5 @@ class Repository(LazyRepository):
Repository.update_forward_refs()
from .issue import Issue

View File

@ -4,7 +4,7 @@
@Author : yanyongyu
@Date : 2021-05-14 00:57:33
@LastEditors : yanyongyu
@LastEditTime : 2021-08-20 23:57:43
@LastEditTime : 2021-09-12 01:04:08
@Description : None
@GitHub : https://github.com/yanyongyu
"""
@ -181,15 +181,6 @@ class TimelineEventUnsubscribed(TimelineEvent):
# Pull Request Reviewed
class TimelineEventReviewedLink(_BaseModel):
href: str
class TimelineEventReviewedLinks(_BaseModel):
html: TimelineEventReviewedLink
pull_request: TimelineEventReviewedLink
class TimelineEventReviewed(TimelineEvent):
event: Literal["reviewed"]
id: int
@ -204,7 +195,6 @@ class TimelineEventReviewed(TimelineEvent):
body: Optional[str]
body_text: Optional[str]
body_html: Optional[str]
links: TimelineEventReviewedLinks = Field(alias="_links")
# Pull Request Review Requested

View File

@ -4,7 +4,7 @@
@Author : yanyongyu
@Date : 2021-05-14 17:09:12
@LastEditors : yanyongyu
@LastEditTime : 2021-09-02 01:27:11
@LastEditTime : 2021-09-12 01:25:26
@Description : None
@GitHub : https://github.com/yanyongyu
"""
@ -76,24 +76,27 @@ env.filters["debug_event"] = debug_event
env.filters["find_dismissed_review"] = find_dismissed_review
#! FIXME
# pr status merged can only be found in timeline events
# or using api: `/repos/{owner}/{repo}/pulls/{pull_number}/merge`
async def issue_to_html(owner: str, repo_name: str, issue: Issue) -> str:
template = env.get_template("issue.html")
async with issue:
timeline = await issue.get_timeline()
pull_request = None
if issue.is_pull_request:
pull_request = await issue.get_pull_request()
return await template.render_async(owner=owner,
repo_name=repo_name,
issue=issue,
pull_request=pull_request,
timeline=timeline)
async def pr_diff_to_html(owner: str, repo_name: str, issue: Issue) -> str:
template = env.get_template("diff.html")
async with issue:
diff = await issue.get_diff()
pull_request = await issue.get_pull_request()
diff = await pull_request.get_diff()
return await template.render_async(owner=owner,
repo_name=repo_name,
issue=issue,
pull_request=pull_request,
diff=PatchSet(diff))

View File

@ -2,7 +2,7 @@
* @Author : yanyongyu
* @Date : 2021-05-17 10:03:08
* @LastEditors : yanyongyu
* @LastEditTime : 2021-09-10 12:38:41
* @LastEditTime : 2021-09-12 02:03:33
* @Description : None
* @GitHub : https://github.com/yanyongyu
-->
@ -33,7 +33,7 @@
<div class="flex-shrink-0 mb-2 flex-self-start flex-md-self-center">
<!-- FIXME: pr status check -->
<!-- prettier-ignore -->
{% if timeline|selectattr("event", "equalto", "merged")|list|length >= 1 %}
{% if pull_request and pull_request.merged %}
{% set state = "merged" -%}
{%- else -%}
{% set state = issue.state %}
@ -52,7 +52,36 @@
</div>
<div class="d-flex flex-items-baseline">
<div class="flex-auto min-width-0 mb-2">
{% if pull_request -%}
<a
class="
author
Link--secondary
text-bold
css-truncate css-truncate-target
"
href="#"
>
{{ pull_request.user.login|escape }}
</a>
<!-- prettier-ignore -->
{% if pull_request.merged -%}
merged
{%- else -%}
wants to merge
{%- endif -%}
{{ pull_request.commits }} commits into
<span class="branch-name css-truncate">
<a class="no-underline">{{ pull_request.base.label|escape }}</a>
</span>
from
<span class="branch-name css-truncate">
<a class="no-underline">{{ pull_request.head.label|escape }}</a>
</span>
<!-- prettier-ignore -->
{%- else -%}
{{ issue.comments }} comments
{%- endif %}
</div>
</div>
</div>