Format, lint, type
This commit is contained in:
parent
a1ae717c8f
commit
c925079e8b
8 changed files with 159 additions and 91 deletions
|
|
@ -1,18 +1,14 @@
|
|||
import re
|
||||
import attr
|
||||
import logging
|
||||
from typing import Any, Tuple
|
||||
from jinja2 import TemplateNotFound
|
||||
import re
|
||||
from typing import Any, List, Tuple
|
||||
|
||||
from mautrix.types import (EventType, RoomID, StateEvent, Membership, MessageType, JSON,
|
||||
TextMessageEventContent, Format, ReactionEventContent, RelationType)
|
||||
import attr
|
||||
from jinja2 import TemplateNotFound
|
||||
from mautrix.types import Format, MessageType, TextMessageEventContent
|
||||
from mautrix.util.formatter import parse_html
|
||||
|
||||
from ..util.template import TemplateManager, TemplateUtil
|
||||
|
||||
from .types import EventParse, OTHER_ENUMS, Action
|
||||
|
||||
from ..common import COLOR_ALARM, COLOR_OK, COLOR_UNKNOWN
|
||||
from .types import OTHER_ENUMS, Action, EventParse # type: ignore
|
||||
|
||||
spaces = re.compile(" +")
|
||||
space = " "
|
||||
|
|
@ -21,22 +17,23 @@ space = " "
|
|||
messages = TemplateManager("gitlab", "messages")
|
||||
templates = TemplateManager("gitlab", "mixins")
|
||||
|
||||
async def parse_event(x_gitlab_event: str, payload: Any) -> Tuple[str, str]:
|
||||
|
||||
async def parse_event(x_gitlab_event: str, payload: Any) -> List[Tuple[str, str]]:
|
||||
evt = EventParse[x_gitlab_event].deserialize(payload)
|
||||
print("processing", evt)
|
||||
try:
|
||||
tpl = messages[evt.template_name]
|
||||
except TemplateNotFound as e:
|
||||
except TemplateNotFound:
|
||||
msg = f"Received unhandled gitlab event type {x_gitlab_event}"
|
||||
logging.info(msg)
|
||||
logging.info(payload)
|
||||
return [(msg, msg)]
|
||||
logging.error(msg)
|
||||
logging.debug(payload)
|
||||
return []
|
||||
|
||||
aborted = False
|
||||
|
||||
def abort() -> None:
|
||||
nonlocal aborted
|
||||
aborted = True
|
||||
|
||||
base_args = {
|
||||
**{field.key: field for field in Action if field.key.isupper()},
|
||||
**OTHER_ENUMS,
|
||||
|
|
@ -45,14 +42,13 @@ async def parse_event(x_gitlab_event: str, payload: Any) -> Tuple[str, str]:
|
|||
|
||||
msgs = []
|
||||
for subevt in evt.preprocess():
|
||||
print("preprocessing", subevt)
|
||||
args = {
|
||||
**attr.asdict(subevt, recurse=False),
|
||||
**{key: getattr(subevt, key) for key in subevt.event_properties},
|
||||
"abort": abort,
|
||||
**base_args,
|
||||
**base_args, # type: ignore
|
||||
}
|
||||
args["templates"] = templates.proxy(args)
|
||||
args["templates"] = templates.proxy(args) # type: ignore
|
||||
|
||||
html = tpl.render(**args)
|
||||
if not html or aborted:
|
||||
|
|
@ -60,11 +56,15 @@ async def parse_event(x_gitlab_event: str, payload: Any) -> Tuple[str, str]:
|
|||
continue
|
||||
html = spaces.sub(space, html.strip())
|
||||
|
||||
content = TextMessageEventContent(msgtype=MessageType.TEXT, format=Format.HTML,
|
||||
formatted_body=html, body=await parse_html(html))
|
||||
content = TextMessageEventContent(
|
||||
msgtype=MessageType.TEXT,
|
||||
format=Format.HTML,
|
||||
formatted_body=html,
|
||||
body=await parse_html(html),
|
||||
)
|
||||
content["xyz.maubot.gitlab.webhook"] = {
|
||||
"event_type": x_gitlab_event,
|
||||
**subevt.meta,
|
||||
}
|
||||
msgs.append((content.body, content.formatted_body))
|
||||
return msgs
|
||||
return msgs
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
# type: ignore
|
||||
# gitlab - A GitLab client and webhook receiver for maubot
|
||||
# Copyright (C) 2019 Lorenz Steinert
|
||||
# Copyright (C) 2021 Tulir Asokan
|
||||
|
|
@ -14,22 +15,27 @@
|
|||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
from typing import List, Union, Dict, Optional, Type, NewType, ClassVar, Tuple, Iterable
|
||||
from datetime import datetime
|
||||
from typing import ClassVar, Dict, Iterable, List, NewType, Optional, Tuple, Type, Union
|
||||
|
||||
from jinja2 import TemplateNotFound
|
||||
from attr import dataclass
|
||||
from yarl import URL
|
||||
import attr
|
||||
|
||||
from mautrix.types import JSON, ExtensibleEnum, SerializableAttrs, serializer, deserializer
|
||||
from attr import dataclass
|
||||
from jinja2 import TemplateNotFound
|
||||
from mautrix.types import (
|
||||
JSON,
|
||||
ExtensibleEnum,
|
||||
SerializableAttrs,
|
||||
deserializer,
|
||||
serializer,
|
||||
)
|
||||
from yarl import URL
|
||||
|
||||
from ..util.contrast import contrast, hex_to_rgb
|
||||
|
||||
|
||||
@serializer(datetime)
|
||||
def datetime_serializer(dt: datetime) -> JSON:
|
||||
return dt.strftime('%Y-%m-%dT%H:%M:%S%z')
|
||||
return dt.strftime("%Y-%m-%dT%H:%M:%S%z")
|
||||
|
||||
|
||||
@deserializer(datetime)
|
||||
|
|
@ -93,9 +99,12 @@ class GitlabLabel(SerializableAttrs):
|
|||
|
||||
@property
|
||||
def foreground_color(self) -> str:
|
||||
return (self.white_hex
|
||||
if contrast(hex_to_rgb(self.color), self.white_rgb) >= self.contrast_threshold
|
||||
else self.black_hex)
|
||||
return (
|
||||
self.white_hex
|
||||
if contrast(hex_to_rgb(self.color), self.white_rgb)
|
||||
>= self.contrast_threshold
|
||||
else self.black_hex
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
@ -133,7 +142,7 @@ class GitlabUser(SerializableAttrs):
|
|||
def __hash__(self) -> int:
|
||||
return self.id
|
||||
|
||||
def __eq__(self, other: 'GitlabUser') -> bool:
|
||||
def __eq__(self, other: "GitlabUser") -> bool:
|
||||
if not isinstance(other, GitlabUser):
|
||||
return False
|
||||
return self.id == other.id
|
||||
|
|
@ -221,7 +230,7 @@ class GitlabSource(SerializableAttrs):
|
|||
http_url: Optional[str] = None
|
||||
|
||||
|
||||
GitlabTarget = NewType('GitlabTarget', GitlabSource)
|
||||
GitlabTarget = NewType("GitlabTarget", GitlabSource)
|
||||
|
||||
|
||||
class GitlabChangeWrapper:
|
||||
|
|
@ -600,7 +609,7 @@ class GitlabBuild(SerializableAttrs):
|
|||
|
||||
@dataclass
|
||||
class GitlabEvent:
|
||||
def preprocess(self) -> List['GitlabEvent']:
|
||||
def preprocess(self) -> List["GitlabEvent"]:
|
||||
return [self]
|
||||
|
||||
@property
|
||||
|
|
@ -641,9 +650,14 @@ class GitlabPushEvent(SerializableAttrs, GitlabEvent):
|
|||
|
||||
@property
|
||||
def user(self) -> GitlabUser:
|
||||
return GitlabUser(id=self.user_id, name=self.user_name, email=self.user_email,
|
||||
username=self.user_username, avatar_url=self.user_avatar,
|
||||
web_url=f"{self.project.gitlab_base_url}/{self.user_username}")
|
||||
return GitlabUser(
|
||||
id=self.user_id,
|
||||
name=self.user_name,
|
||||
email=self.user_email,
|
||||
username=self.user_username,
|
||||
avatar_url=self.user_avatar,
|
||||
web_url=f"{self.project.gitlab_base_url}/{self.user_username}",
|
||||
)
|
||||
|
||||
@property
|
||||
def template_name(self) -> str:
|
||||
|
|
@ -651,8 +665,15 @@ class GitlabPushEvent(SerializableAttrs, GitlabEvent):
|
|||
|
||||
@property
|
||||
def event_properties(self) -> Iterable[str]:
|
||||
return ("user", "is_new_ref", "is_deleted_ref", "ref_name", "ref_type", "ref_url",
|
||||
"diff_url")
|
||||
return (
|
||||
"user",
|
||||
"is_new_ref",
|
||||
"is_deleted_ref",
|
||||
"ref_name",
|
||||
"ref_type",
|
||||
"ref_url",
|
||||
"diff_url",
|
||||
)
|
||||
|
||||
@property
|
||||
def diff_url(self) -> str:
|
||||
|
|
@ -695,7 +716,9 @@ class GitlabPushEvent(SerializableAttrs, GitlabEvent):
|
|||
return f"push-{self.project_id}-{self.checkout_sha}-{self.ref_name}"
|
||||
|
||||
|
||||
def split_updates(evt: Union['GitlabIssueEvent', 'GitlabMergeRequestEvent']) -> List[GitlabEvent]:
|
||||
def split_updates(
|
||||
evt: Union["GitlabIssueEvent", "GitlabMergeRequestEvent"]
|
||||
) -> List[GitlabEvent]:
|
||||
if not evt.changes:
|
||||
return [evt]
|
||||
output = []
|
||||
|
|
@ -704,7 +727,9 @@ def split_updates(evt: Union['GitlabIssueEvent', 'GitlabMergeRequestEvent']) ->
|
|||
for field in attr.fields(GitlabChanges):
|
||||
value = getattr(evt.changes, field.name)
|
||||
if value:
|
||||
output.append(attr.evolve(evt, changes=GitlabChanges(**{field.name: value})))
|
||||
output.append(
|
||||
attr.evolve(evt, changes=GitlabChanges(**{field.name: value}))
|
||||
)
|
||||
return output
|
||||
|
||||
|
||||
|
|
@ -719,7 +744,7 @@ class GitlabIssueEvent(SerializableAttrs, GitlabEvent):
|
|||
labels: Optional[List[GitlabLabel]] = None
|
||||
changes: Optional[GitlabChanges] = None
|
||||
|
||||
def preprocess(self) -> List['GitlabIssueEvent']:
|
||||
def preprocess(self) -> List["GitlabIssueEvent"]:
|
||||
users_to_mutate = [self.user]
|
||||
if self.changes and self.changes.assignees:
|
||||
users_to_mutate += self.changes.assignees.previous
|
||||
|
|
@ -737,7 +762,7 @@ class GitlabIssueEvent(SerializableAttrs, GitlabEvent):
|
|||
|
||||
@property
|
||||
def event_properties(self) -> Iterable[str]:
|
||||
return "action",
|
||||
return ("action",)
|
||||
|
||||
@property
|
||||
def action(self) -> Action:
|
||||
|
|
@ -757,7 +782,7 @@ class GitlabCommentEvent(SerializableAttrs, GitlabEvent):
|
|||
issue: Optional[GitlabIssue] = None
|
||||
snippet: Optional[GitlabSnippet] = None
|
||||
|
||||
def preprocess(self) -> List['GitlabCommentEvent']:
|
||||
def preprocess(self) -> List["GitlabCommentEvent"]:
|
||||
self.user.web_url = f"{self.project.gitlab_base_url}/{self.user.username}"
|
||||
return [self]
|
||||
|
||||
|
|
@ -776,7 +801,7 @@ class GitlabMergeRequestEvent(SerializableAttrs, GitlabEvent):
|
|||
labels: List[GitlabLabel]
|
||||
changes: GitlabChanges
|
||||
|
||||
def preprocess(self) -> List['GitlabMergeRequestEvent']:
|
||||
def preprocess(self) -> List["GitlabMergeRequestEvent"]:
|
||||
users_to_mutate = [self.user]
|
||||
if self.changes and self.changes.assignees:
|
||||
users_to_mutate += self.changes.assignees.previous
|
||||
|
|
@ -792,7 +817,7 @@ class GitlabMergeRequestEvent(SerializableAttrs, GitlabEvent):
|
|||
|
||||
@property
|
||||
def event_properties(self) -> Iterable[str]:
|
||||
return "action",
|
||||
return ("action",)
|
||||
|
||||
@property
|
||||
def action(self) -> Action:
|
||||
|
|
@ -807,7 +832,7 @@ class GitlabWikiPageEvent(SerializableAttrs, GitlabEvent):
|
|||
wiki: GitlabWiki
|
||||
object_attributes: GitlabWikiPageAttributes
|
||||
|
||||
def preprocess(self) -> List['GitlabWikiPageEvent']:
|
||||
def preprocess(self) -> List["GitlabWikiPageEvent"]:
|
||||
self.user.web_url = f"{self.project.gitlab_base_url}/{self.user.username}"
|
||||
return [self]
|
||||
|
||||
|
|
@ -862,7 +887,7 @@ class GitlabJobEvent(SerializableAttrs, GitlabEvent):
|
|||
repository: GitlabRepository
|
||||
runner: Optional[GitlabRunner]
|
||||
|
||||
def preprocess(self) -> List['GitlabJobEvent']:
|
||||
def preprocess(self) -> List["GitlabJobEvent"]:
|
||||
base_url = str(URL(self.repository.homepage).with_path(""))
|
||||
self.user.web_url = f"{base_url}/{self.user.username}"
|
||||
return [self]
|
||||
|
|
@ -894,20 +919,22 @@ class GitlabJobEvent(SerializableAttrs, GitlabEvent):
|
|||
|
||||
@property
|
||||
def event_properties(self) -> Iterable[str]:
|
||||
return "build_url",
|
||||
return ("build_url",)
|
||||
|
||||
@property
|
||||
def build_url(self) -> str:
|
||||
return f"{self.repository.homepage}/-/jobs/{self.build_id}"
|
||||
|
||||
|
||||
GitlabEventType = Union[Type[GitlabPushEvent],
|
||||
Type[GitlabIssueEvent],
|
||||
Type[GitlabCommentEvent],
|
||||
Type[GitlabMergeRequestEvent],
|
||||
Type[GitlabWikiPageEvent],
|
||||
Type[GitlabPipelineEvent],
|
||||
Type[GitlabJobEvent]]
|
||||
GitlabEventType = Union[
|
||||
Type[GitlabPushEvent],
|
||||
Type[GitlabIssueEvent],
|
||||
Type[GitlabCommentEvent],
|
||||
Type[GitlabMergeRequestEvent],
|
||||
Type[GitlabWikiPageEvent],
|
||||
Type[GitlabPipelineEvent],
|
||||
Type[GitlabJobEvent],
|
||||
]
|
||||
|
||||
EventParse: Dict[str, GitlabEventType] = {
|
||||
"Push Hook": GitlabPushEvent,
|
||||
|
|
@ -919,7 +946,7 @@ EventParse: Dict[str, GitlabEventType] = {
|
|||
"Merge Request Hook": GitlabMergeRequestEvent,
|
||||
"Wiki Page Hook": GitlabWikiPageEvent,
|
||||
"Pipeline Hook": GitlabPipelineEvent,
|
||||
"Job Hook": GitlabJobEvent
|
||||
"Job Hook": GitlabJobEvent,
|
||||
}
|
||||
|
||||
OTHER_ENUMS = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue