From: Jean Privat Date: Sat, 28 Nov 2015 23:04:07 +0000 (-0500) Subject: Merge: nitiwiki: fix multiple trails X-Git-Tag: v0.8~71 X-Git-Url: http://nitlanguage.org?hp=f574c453106218667d762d628e77ef82dc5fe720 Merge: nitiwiki: fix multiple trails Fix a bug where independent trails could have been merged into a big one. Pull-Request: #1854 Reviewed-by: Alexandre Terrasa --- diff --git a/contrib/nitrpg/src/achievements.nit b/contrib/nitrpg/src/achievements.nit index 9b18a6b..5ce317a 100644 --- a/contrib/nitrpg/src/achievements.nit +++ b/contrib/nitrpg/src/achievements.nit @@ -74,10 +74,15 @@ end class Achievement super GameEntity - redef var key is lazy do return "achievements" / id redef var game + redef var key is lazy do + var owner = self.owner + if owner == null then return id + return "{owner.key}-{id}" + end + # Uniq ID for this achievement. var id: String @@ -93,6 +98,9 @@ class Achievement # Is this achievement unlocked by somebody? var is_unlocked: Bool is lazy do return not load_events.is_empty + # Game entity this achievement is about. + var owner: nullable GameEntity = null + # Init `self` from a `json` object. # # Used to load achievements from storage. @@ -106,6 +114,8 @@ class Achievement json["name"] = name json["desc"] = desc json["reward"] = reward + json["game"] = game.key + if owner != null then json["owner"] = owner.key return json end end @@ -346,7 +356,7 @@ abstract class PlayerXCommits if not event.action == "closed" then return if not event.pull.merged then return var player = event.pull.user.player(game) - if player.stats["commits"] == threshold then + if player.stats["commits"] >= threshold then var a = new_achievement(game) player.unlock_achievement(a, event) end @@ -447,7 +457,7 @@ end class Player1KComments super PlayerXComments - redef var id = "player_1000__comments" + redef var id = "player_1000_comments" redef var name = "You sir, talk a lot!" redef var desc = "Comment 1000 times on issues." redef var reward = 1000 diff --git a/contrib/nitrpg/src/events.nit b/contrib/nitrpg/src/events.nit index d1ba25a..bd1ee58 100644 --- a/contrib/nitrpg/src/events.nit +++ b/contrib/nitrpg/src/events.nit @@ -24,8 +24,10 @@ import game redef class GameEntity - # Saves `event` in `self`. - fun add_event(event: GameEvent) do event.save_in(self.key) + fun add_event(event: GameEvent) do + event.owner = self + event.save + end # List all events registered in this entity. # @@ -61,10 +63,12 @@ end class GameEvent super GameEntity - redef var key is lazy do return "events" / internal_id redef var game + # Entity this event belongs to. + var owner: nullable GameEntity = null + # String used to dissociate events in the display. var kind: String @@ -76,6 +80,8 @@ class GameEvent # GameEvent uniq id used for storage. var internal_id: String is noinit + redef var key = internal_id is lazy + # Date and time of the event. var time: ISODate is noinit, writable @@ -100,6 +106,8 @@ class GameEvent json["kind"] = kind json["time"] = time.to_s json["data"] = data + json["game"] = game.key + if owner != null then json["owner"] = owner.key return json end end diff --git a/contrib/nitrpg/src/game.nit b/contrib/nitrpg/src/game.nit index a109949..2924e46 100644 --- a/contrib/nitrpg/src/game.nit +++ b/contrib/nitrpg/src/game.nit @@ -65,20 +65,20 @@ class Game redef fun game do return self - # Returns the repo `full_name`. - # - # Example: `"nitlang/nit"` - redef fun key do return repo.full_name - # We need a `GithubAPI` client to load Github data. var api: GithubAPI # A game takes place in a `github::Repo`. var repo: Repo + # Game name + var name: String = repo.full_name is lazy + # Directory where game data are stored. var game_dir: String is lazy do return "nitrpg_data" / repo.full_name + redef var key = name is lazy + # Used for data storage. # # File are stored in `game_dir`. @@ -92,6 +92,12 @@ class Game # Used to load entities from saved data. fun from_json(json: JsonObject) do end + redef fun to_json do + var json = super + json["name"] = name + return json + end + # Create a player from a Github `User`. # # Or return the existing one from game data. @@ -180,9 +186,6 @@ end class Player super GameEntity - # Key is based on player `name`. - redef var key is lazy do return "players" / name - redef var game # FIXME contructor should be private @@ -195,6 +198,8 @@ class Player # The name is also used to load the user data lazilly from Github API. var name: String + redef var key = name is lazy + # Player amount of nitcoins. # # Nitcoins is the currency used in nitrpg. @@ -218,6 +223,7 @@ class Player redef fun to_json do var json = super + json["game"] = game.key json["name"] = name json["nitcoins"] = nitcoins return json diff --git a/contrib/nitrpg/src/reactors.nit b/contrib/nitrpg/src/reactors.nit index 7073c98..e2717f4 100644 --- a/contrib/nitrpg/src/reactors.nit +++ b/contrib/nitrpg/src/reactors.nit @@ -58,7 +58,7 @@ redef class PullRequestEvent # Rewards player for opened pull requests. redef fun react_player_event(r, game) do - if action == "opened" then + if action == "opened" or action == "reopened" then react_pull_open(r, game) else if action == "closed" then react_pull_close(r, game) @@ -95,14 +95,18 @@ redef class IssueCommentEvent # Rewards player for review comments. # # TODO only give nitcoins if reviewers < 2 + # TODO give more points to first reviewer redef fun react_player_event(r, game) do if comment.is_ack then react_player_review(r, game) end end + # TODO same player should not be authorized to review multiple times? How to handle rerols? private fun react_player_review(r: PlayerReactor, game: Game) do + if issue.state == "closed" then return var player = comment.user.player(game) + if issue.user == player.user then return player.nitcoins += r.nc_pull_review player.save var event = player_reward_event("pull_review", player, r.nc_pull_review) diff --git a/contrib/nitrpg/src/statistics.nit b/contrib/nitrpg/src/statistics.nit index b7d3530..153b5cd 100644 --- a/contrib/nitrpg/src/statistics.nit +++ b/contrib/nitrpg/src/statistics.nit @@ -79,49 +79,32 @@ class GameStatsManager # The GameEntity monitored by these statistics. var owner: GameEntity - redef var key = "stats" + # Current date to extract stats + private var date = new Tm.gmtime # Returns the `GameStats` instance for the overall statistics. - var overall: GameStats is lazy do - return load_stats_for("all") - end + var overall: GameStats = load_stats_for("all") is lazy # Returns the `GameStats` instance for the current year statistics. - var yearly: GameStats is lazy do - var date = new Tm.gmtime - var key = date.strftime("%Y") - return load_stats_for(key) - end + var yearly: GameStats = load_stats_for(date.strftime("%Y")) is lazy # Returns the `GameStats` instance for the current month statistics. - var monthly: GameStats is lazy do - var date = new Tm.gmtime - var key = date.strftime("%Y-%m") - return load_stats_for(key) - end + var monthly: GameStats = load_stats_for(date.strftime("%Y-%m")) is lazy # Returns the `GameStats` instance for the current day statistics. - var daily: GameStats is lazy do - var date = new Tm.gmtime - var key = date.strftime("%Y-%m-%d") - return load_stats_for(key) - end + var daily: GameStats = load_stats_for(date.strftime("%Y-%m-%d")) is lazy # Returns the `GameStats` instance for the current week statistics. - var weekly: GameStats is lazy do - var date = new Tm.gmtime - var key = date.strftime("%Y-W%U") - return load_stats_for(key) - end + var weekly: GameStats = load_stats_for(date.strftime("%Y-W%U")) is lazy # Load statistics for a `period` key. fun load_stats_for(period: String): GameStats do var key = owner.key / self.key / period if not game.store.has_key(key) then - return new GameStats(game, period) + return new GameStats(game, period, owner) end var json = game.store.load_object(key) - return new GameStats.from_json(game, period, json) + return new GameStats.from_json(game, period, owner, json) end redef fun [](key) do return overall[key] @@ -168,19 +151,28 @@ class GameStats redef var game - # The pedriod these stats are about. + # The period these stats are about. var period: String - redef fun key do return period + # The game entity these stats are about. + var owner: GameEntity + + redef var key = "{owner.key}-{period}" is lazy # Load `self` from saved data. - init from_json(game: Game, period: String, json: JsonObject) do - for k, v in json do self[k] = v.as(Int) + init from_json(game: Game, period: String, owner: GameEntity, json: JsonObject) do + var values = json.get_or_null("values") + if not values isa JsonObject then return + for k, v in values do self[k] = v.as(Int) end redef fun to_json do - var obj = new JsonObject - for k, v in self do obj[k] = v + var obj = super + obj["period"] = period + obj["owner"] = owner.key + var values = new JsonObject + values.recover_with(self) + obj["values"] = values return obj end diff --git a/contrib/nitrpg/src/templates/templates_base.nit b/contrib/nitrpg/src/templates/templates_base.nit index 8b85a4d..a4f40d9 100644 --- a/contrib/nitrpg/src/templates/templates_base.nit +++ b/contrib/nitrpg/src/templates/templates_base.nit @@ -34,9 +34,6 @@ redef class Game redef fun url do return "{root_url}/games" / key - # Displayed name. - fun name: String do return repo.full_name - # Return a HTML link to this Game. fun link: String do return "{name}" end