Skip to content

Commit 6340210

Browse files
authored
✨ add event parsing
1 parent 5d7463a commit 6340210

File tree

4 files changed

+334
-7
lines changed

4 files changed

+334
-7
lines changed

codegen/__init__.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
from pathlib import Path
33
from itertools import chain
44
from dataclasses import dataclass
5-
from typing import List, Union, get_args, get_origin
5+
from typing import Dict, List, Union, get_args, get_origin
66

77
from jinja2 import Environment, PackageLoader
88
from githubkit.webhooks.models import GitHubWebhookModel
@@ -38,16 +38,21 @@ def pascal_case(*names: str) -> str:
3838
def build_event():
3939
imports: List[str] = []
4040
events: List[Data] = []
41+
event_types: Dict[str, Union[str, Dict[str, str]]] = {}
4142
for event, types in webhook_action_types.items():
4243
if not isinstance(types, dict):
4344
imports.append(f"{types.__name__} as {types.__name__}Payload")
4445
events.append(Data(types.__name__, f"{types.__name__}Payload"))
46+
event_types[event] = types.__name__
4547
continue
4648

49+
action_types: Dict[str, str] = {}
50+
event_types[event] = action_types
4751
for action, type in types.items():
4852
if inspect.isclass(type) and issubclass(type, GitHubWebhookModel):
4953
imports.append(f"{type.__name__} as {type.__name__}Payload")
5054
events.append(Data(type.__name__, f"{type.__name__}Payload"))
55+
action_types[action] = type.__name__
5156
else:
5257
assert get_origin(type) is Union
5358
imports.extend(model.__name__ for model in get_args(type))
@@ -57,12 +62,14 @@ def build_event():
5762
f"Union[{', '.join(model.__name__ for model in get_args(type))}]",
5863
)
5964
)
65+
action_types[action] = pascal_case(event, action)
6066

6167
env = Environment(loader=PackageLoader("codegen"))
6268
template = env.get_template("event.py.jinja")
6369
event_text = template.render(
6470
imports=imports,
6571
events=events,
72+
types=event_types,
6673
message_events=MESSAGE_EVENTS,
6774
has_message_events=HAS_MESSAGE_EVENTS,
6875
)

codegen/templates/event.py.jinja

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,17 @@ class {{ event.class_name }}(Event):
8787

8888
{% endif %}
8989
{% endfor %}
90+
91+
events = {
92+
{% for event, types in types.items() %}
93+
{% if types is mapping %}
94+
"{{ event }}": {
95+
{% for action, type in types.items() %}
96+
"{{ action }}": {{ type }},
97+
{% endfor %}
98+
},
99+
{% else %}
100+
"{{ event }}": {{ types }},
101+
{% endif %}
102+
{% endfor %}
103+
}

nonebot/adapters/github/adapter.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import json
12
import asyncio
3+
import inspect
24
from functools import partial
35
from typing import Any, Union, Optional, cast
46

@@ -16,7 +18,7 @@
1618
from nonebot.adapters import Adapter as BaseAdapter
1719

1820
from .utils import log
19-
from .event import Event
21+
from .event import Event, events
2022
from .bot import Bot, OAuthBot, GitHubBot
2123
from .config import Config, OAuthApp, GitHubApp
2224

@@ -96,8 +98,25 @@ async def _handle_webhook(
9698
def payload_to_event(
9799
cls, event_id: str, event_name: str, payload: Union[str, bytes]
98100
) -> Optional[Event]:
101+
event_payload = json.loads(payload)
99102
try:
100-
payload_event = parse(event_name, payload)
101-
# TODO
103+
types = events.get(event_name)
104+
if isinstance(types, dict):
105+
if action := event_payload.get("action"):
106+
return types[action].parse_obj(
107+
{"id": event_id, "name": event_name, "payload": event_payload}
108+
)
109+
else:
110+
raise ValueError(
111+
f"Payload missing action, either of {', '.join(types)}."
112+
)
113+
elif types is None:
114+
raise ValueError(f"Unknown event type {event_name}.")
115+
return types.parse_obj(
116+
{"id": event_id, "name": event_name, "payload": event_payload}
117+
)
102118
except Exception as e:
103-
log("ERROR", f"Failed to parse webhook payload {event_id}", e)
119+
log("WARNING", f"Failed to parse webhook payload {event_id}", e)
120+
return Event.parse_obj(
121+
{"id": event_id, "name": event_name, "payload": event_payload}
122+
)

0 commit comments

Comments
 (0)