1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Github hook event listening with `nitcorn`.
20 # import github::hooks
22 # # A simple hook listener that print received events in stdout.
23 # class LogHookListener
26 # # Use double dispatch to implement log behavior.
27 # redef fun apply_event(event) do event.log_event(self)
30 # redef class GithubEvent
33 # # Do nothing by default.
34 # fun log_event(l: LogHookListener) do end
37 # redef class CommitCommentEvent
39 # redef fun log_event(l) do
40 # print "new comment on commit {comment.commit.sha}"
44 # var api = new GithubAPI(get_github_oauth)
45 # var listener = new LogHookListener(api, "127.0.0.1", 8080)
46 # # listener.listen # uncomment to start listening
53 # A nitcorn listener for Github hooks.
54 abstract class HookListener
56 # Api client used to perform Github API requests.
65 # VirtualHost listened
66 private var vh
: VirtualHost is noinit
69 vh
= new VirtualHost("{host}:{port}")
70 vh
.routes
.add
new Route("/", new HookAction(self))
73 # Verbosity level (0: quiet, 1: debug).
77 # Print `message` if `lvl` <= `verbosity`
78 fun message
(lvl
: Int, message
: String) do
79 if lvl
<= verbosity
then print message
82 # Start listening and responding to event.
84 message
(1, "Hook listening on {host}:{port}")
85 var factory
= new HttpFactory.and_libevent
86 factory
.config
.virtual_hosts
.add vh
90 # How to build events from received json objects.
91 fun event_factory
(kind
: String, json
: JsonObject): GithubEvent do
92 if kind
== "commit_comment" then
93 return new CommitCommentEvent.from_json
(api
, json
)
94 else if kind
== "create" then
95 return new CreateEvent.from_json
(api
, json
)
96 else if kind
== "delete" then
97 return new DeleteEvent.from_json
(api
, json
)
98 else if kind
== "deployment" then
99 return new DeploymentEvent.from_json
(api
, json
)
100 else if kind
== "deployment_status" then
101 return new DeploymentStatusEvent.from_json
(api
, json
)
102 else if kind
== "fork" then
103 return new ForkEvent.from_json
(api
, json
)
104 else if kind
== "issues" then
105 return new IssuesEvent.from_json
(api
, json
)
106 else if kind
== "issue_comment" then
107 return new IssueCommentEvent.from_json
(api
, json
)
108 else if kind
== "member" then
109 return new MemberEvent.from_json
(api
, json
)
110 else if kind
== "pull_request" then
111 return new PullRequestEvent.from_json
(api
, json
)
112 else if kind
== "pull_request_review_comment" then
113 return new PullRequestReviewCommentEvent.from_json
(api
, json
)
114 else if kind
== "push" then
115 return new PushEvent.from_json
(api
, json
)
116 else if kind
== "status" then
117 return new StatusEvent.from_json
(api
, json
)
119 return new GithubEvent.from_json
(api
, json
)
123 # What to do when we receive an event from a hook?
124 fun apply_event
(event
: GithubEvent) is abstract
127 # A nitcorn action dedicated to GitHub hook listening.
128 private class HookAction
131 # Listener that contains this action.
133 # The `listener` is used for its `event_factory` method
134 # and the `apply_event`.
135 var listener
: HookListener
137 # Parse hook request then call `listener.apply_event`.
138 redef fun answer
(request
, uri
) do
140 var kind
= request
.header
.get_or_null
("X-GitHub-Event")
141 if kind
== null then return new HttpResponse(403)
143 var obj
= request
.body
.parse_json
144 if not obj
isa JsonObject then return new HttpResponse(403)
146 var event
= listener
.event_factory
(kind
, obj
)
147 listener
.apply_event
(event
)
148 return new HttpResponse(200)