65d5a695785a60ada2df88c5168766b118290cf0
[nit.git] / contrib / nitrpg / src / statistics.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2014-2015 Alexandre Terrasa <alexandre@moz-code.org>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Statistics about the Game.
18 #
19 # This module uses `GameReactor` to extract statistics about the game from
20 # triggered `Github::Event`.
21 module statistics
22
23 import game
24 import github::hooks
25
26 redef class Game
27
28 # Statistics for this game instance.
29 var stats = new GameStats
30
31 redef fun from_json(json) do
32 super
33 if json.has_key("statistics") then
34 stats.from_json(json["statistics"].as(JsonObject))
35 end
36 end
37
38 redef fun to_json do
39 var obj = super
40 obj["statistics"] = stats.to_json
41 return obj
42 end
43
44 redef fun pretty do
45 var res = new FlatBuffer
46 res.append super
47 res.append "# stats:\n"
48 res.append stats.pretty
49 return res.write_to_string
50 end
51
52 redef fun clear do
53 super
54 stats.clear
55 end
56 end
57
58 # Game statistics structure that can be saved as a `GameEntity`.
59 class GameStats
60 super GameEntity
61
62 redef var key = "statistics"
63
64 # Used internally to stats values.
65 private var stats = new HashMap[String, Int]
66
67 init do clear
68
69 # Load `self` from saved data
70 private fun from_json(json: JsonObject) do
71 for k, v in json do stats[k] = v.as(Int)
72 end
73
74 redef fun to_json do
75 var obj = new JsonObject
76 for k, v in stats do obj[k] = v
77 return obj
78 end
79
80 # Retrieves the current value of `key` statistic entry.
81 fun [](key: String): Int do return stats[key]
82
83 # Increments the value of `key` statistic entry by 1.
84 fun incr(key: String) do stats[key] += 1
85
86 # Decrements the value of `key` statistic entry by 1.
87 fun decr(key: String) do stats[key] -= 1
88
89 # Reset game stats.
90 fun clear do
91 stats["issues"] = 0
92 stats["issues_open"] = 0
93 stats["pulls"] = 0
94 stats["pulls_open"] = 0
95 end
96
97 redef fun pretty do
98 var res = new FlatBuffer
99 for k, v in stats do
100 res.append "# {v} {k}\n"
101 end
102 return res.write_to_string
103 end
104 end
105
106 # `GameReactor` that computes statistics about the game.
107 class StatisticsReactor
108 super GameReactor
109
110 redef fun react_event(game, e) do
111 super # log events
112 e.react_stats_event(game)
113 game.save
114 end
115 end
116
117 redef class GithubEvent
118 # Reacts to a statistics related event.
119 #
120 # Called by `StatisticsReactor::react_event`.
121 # No-op by default.
122 private fun react_stats_event(game: Game) do end
123 end
124
125 redef class IssuesEvent
126
127 # Count opened and closed issues.
128 redef fun react_stats_event(game) do
129 if action == "opened" then
130 game.stats.incr("issues")
131 game.stats.incr("issues_open")
132 else if action == "reopened" then
133 game.stats.incr("issues_open")
134 else if action == "closed" then
135 game.stats.decr("issues_open")
136 end
137 end
138 end
139
140 redef class PullRequestEvent
141
142 # Count opened and closed pull requests.
143 redef fun react_stats_event(game) do
144 if action == "opened" then
145 game.stats.incr("pulls")
146 game.stats.incr("pulls_open")
147 else if action == "reopened" then
148 game.stats.incr("pulls_open")
149 else if action == "closed" then
150 game.stats.decr("pulls_open")
151 end
152 end
153 end