forked from tobymao/18xx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
import_game.rb
103 lines (88 loc) · 2.85 KB
/
import_game.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# frozen_string_literal: true
require 'argon2'
require 'net/http'
require 'uri'
require_relative 'db'
require_relative 'models'
require_relative 'models/action'
require_relative 'models/game'
require_relative 'models/game_user'
require_relative 'models/user'
raise 'You probably only want to import games into dev servers' unless ENV['RACK_ENV'] == 'development'
def import_game(game_id)
game_uri = URI.parse("https://18xx.games/api/game/#{game_id}")
res = Net::HTTP.get_response game_uri
game_json_string = res.body
game_json = JSON.parse(game_json_string)
actions_json = game_json.delete('actions')
# Synthetic: Whether actions were included
game_json.delete('loaded')
players_json = game_json.delete('players')
user_json = game_json.delete('user')
# Create users that don't already exist
User.unrestrict_primary_key
players_json.each do |player_json|
player_id = player_json['id']
name = player_json['name']
next if User[id: player_id]
params = {
id: player_id,
name: name,
email: "#{name.gsub(/\s/, '_')}@example.com",
password: 'password',
settings: {
notifications: 'none',
webhook: nil,
webhook_url: nil,
webhook_user_id: nil,
},
}
User.create(params)
end
User.restrict_primary_key
# Clean up game json
game_json['created_at'] = Time.at(game_json['created_at'])
game_json['updated_at'] = Time.at(game_json['updated_at'])
game_json['user_id'] = user_json['id']
# Synthetic: Denormalized user-specific subset of settings
game_json.delete('user_settings')
game = Game[id: game_id]
Game.unrestrict_primary_key
if game
# Update existing game
game.update(game_json)
# Filter out actions already in the database
max_existing_action_id = Action.where(game_id: game.id).max(:action_id)
actions_json.delete_if { |action_json| action_json['id'] <= max_existing_action_id }
else
# Create new game
game = Game.create(game_json)
# Add users
players_json.each do |player_json|
player_id = player_json['id']
user = User[id: player_id]
GameUser.create(game: game, user: user)
end
end
Game.restrict_primary_key
# Apply new actions
actions_json.each do |action_json|
user_id = action_json['user']
action_id = action_json['id']
created_at = Time.at(action_json['created_at'])
action_json['created_at'] = created_at
# User field is unpredictable, but this seems to match behavior reasonably well.
action_json.delete('user') if action_json['entity_type'] == 'player' && action_json['entity'] == action_json['user']
Action.create(
game: game,
user_id: user_id,
action_id: action_id,
action: action_json,
created_at: created_at,
)
end
game.id
end
def fix_existing_users
DB[:users].update(password: Argon2::Password.create('password'))
end