aromancer 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,414 @@
1
+ # frozen_string_literal: true
2
+
3
+ =begin
4
+
5
+ routes.rb
6
+
7
+ view routing and configuration.
8
+
9
+ by i2097i
10
+
11
+ =end
12
+
13
+ module Aromancer
14
+ class Routes
15
+
16
+ def self.cls
17
+ TTY::Cursor.clear_screen
18
+ TTY::Cursor.clear_screen_up
19
+ end
20
+
21
+ def self.authentication(require_key_press = false)
22
+ Aromancer::Prompt.say(I18n.t("shared.navigate", route: :authentication))
23
+ Aromancer::Prompt.p.ask(I18n.t("shared.key_press")) if require_key_press
24
+
25
+ choices = [
26
+ {name: I18n.t("routes.authentication.sign_in"), value: :in},
27
+ {name: I18n.t("routes.authentication.sign_up"), value: :up},
28
+ {name: I18n.t("shared.exit"), value: :exit}
29
+ ]
30
+ text = ""#Aromancer.get_font(I18n.t("routes.authentication.title")).join("\n") +
31
+ "\n#{I18n.t("routes.authentication.subtitle")}"
32
+ case Aromancer::Prompt.p.select(text, choices, show_help: :always, cycle: true, per_page: 11)
33
+ when :in
34
+ Aromancer::Api.sign_in
35
+ when :up
36
+ Aromancer::Api.sign_up
37
+ else
38
+ exit
39
+ end
40
+
41
+ if Aromancer::Storage.get_player
42
+ Aromancer::Storage.set_signed_out_flag(false)
43
+ main_menu
44
+ else
45
+ Aromancer.print_last_error("routes.authentication.failed")
46
+ authentication(true)
47
+ end
48
+ end
49
+
50
+ def self.active_legend
51
+ Aromancer::Api.get_legends
52
+ Aromancer::Storage.get_legends.select{|l| l["id"] == Aromancer::Storage.get_player["active_legend_id"]}.first
53
+ end
54
+
55
+ def self.main_menu
56
+ cls
57
+ Aromancer::Prompt.say(I18n.t("shared.navigate", route: :main_menu))
58
+ if Aromancer::Storage.get_signed_out_flag
59
+ Aromancer::Prompt.say(I18n.t("routes.main_menu.not_signed_in"))
60
+ Aromancer::Api.sign_out
61
+ return authentication
62
+ end
63
+
64
+ player = Aromancer::Storage.get_player&.symbolize_keys
65
+ al = active_legend
66
+ return legend_menu if (!player.nil? && !player[:active_legend_id].nil?) ||
67
+ (!al.nil? && al["status"] == "started")
68
+
69
+ choices = [
70
+ {name: I18n.t("routes.main_menu.new_game"), value: :new},
71
+ {name: I18n.t("routes.main_menu.load_game"), value: :load},
72
+ {name: I18n.t("routes.main_menu.sign_out"), value: :out},
73
+ {name: I18n.t("shared.exit"), value: :exit}
74
+ ]
75
+ text = ""#Aromancer.get_font(I18n.t("routes.main_menu.title")).join("\n") +
76
+ "\n#{I18n.t("routes.main_menu.subtitle")}"
77
+ case Aromancer::Prompt.p.select(text, choices, show_help: :always, cycle: true, per_page: 11)
78
+ when :new
79
+ new_game
80
+ when :load
81
+ legends
82
+ when :out
83
+ case Aromancer::Prompt.p.select(I18n.t("shared.confirm"), [:no, :yes], cycle: true, per_page: 11)
84
+ when :no
85
+ main_menu
86
+ when :yes
87
+ Aromancer::Api.sign_out
88
+ authentication
89
+ end
90
+ else
91
+ exit
92
+ end
93
+ end
94
+
95
+ def self.new_game
96
+ cls
97
+ Aromancer::Prompt.say(I18n.t("shared.navigate", route: :new_game))
98
+ params = Aromancer::Api::DEFAULT_LEGEND_PARAMS.dup
99
+ data = [
100
+ [I18n.t("routes.new_game.player_count"), params[:player_count]],
101
+ [I18n.t("routes.new_game.story_count"), params[:story_count]],
102
+ [I18n.t("routes.new_game.status"), params[:status]]
103
+ ]
104
+ table = TTY::Table.new(data)
105
+ Aromancer::Prompt.say(table.render(:unicode))
106
+
107
+ # TODO: edit params here
108
+
109
+ Aromancer::Prompt.say(I18n.t("routes.new_game.starting"))
110
+ Aromancer::Api.create_legend(params)
111
+ Aromancer::Prompt.p.ask(I18n.t("shared.key_press"))
112
+
113
+ main_menu
114
+ end
115
+
116
+ def self.legends
117
+ Aromancer::Api.get_legends
118
+ legend_array = Aromancer::Storage.get_legends
119
+ unless legend_array.any?
120
+ Aromancer::Prompt.say(I18n.t("shared.empty"))
121
+ Aromancer::Prompt.p.ask(I18n.t("shared.key_press"))
122
+ main_menu
123
+ end
124
+ choices = [{name: :back, value: :back}] + legend_array.map{|l|
125
+ {
126
+ name: "#{I18n.t("routes.legend.title")}_#{l["id"]} (#{l["status"]}) #{DateTime.parse(l["created_at"])&.strftime(Aromancer::Api::DATE_FORMAT)}",
127
+ value: l["id"]
128
+ }
129
+ }
130
+ selected_legend_id = Aromancer::Prompt.p.select("", choices, help: I18n.t("routes.legends.help"), show_help: :always, cycle: true, per_page: 11)
131
+
132
+ if selected_legend_id == :back
133
+ return main_menu
134
+ end
135
+
136
+ Aromancer::Api.set_active_legend_id(selected_legend_id)
137
+ legend_menu
138
+ end
139
+
140
+ def self.stream
141
+ Aromancer::Api.load_stream
142
+ stream = Aromancer::Storage.get_stream
143
+ Aromancer::Prompt.say(I18n.t("routes.stream.title"))
144
+ Aromancer::Prompt.say([
145
+ :timestamp,
146
+ :description
147
+ ].join(", "))
148
+
149
+ stream["stream"].each{|e|
150
+ Aromancer::Prompt.say("\n")
151
+ Aromancer::Prompt.say([e["updated_at"], e["description"]].join("\n"))
152
+ }
153
+ Aromancer::Prompt.p.ask(I18n.t("shared.key_press"))
154
+ legend_menu
155
+ end
156
+
157
+ def self.legend_menu
158
+ cls
159
+ # Aromancer::Prompt.say(I18n.t("shared.navigate", route: :legend_menu))
160
+ legend
161
+
162
+ legend_array = Aromancer::Storage.get_legends
163
+ al = active_legend
164
+ if !al.nil? && al["status"] == "complete"
165
+ Aromancer::Api.set_active_legend_id(nil)
166
+ Aromancer::Prompt.say(I18n.t("routes.legend.legend_complete"))
167
+ Aromancer::Prompt.p.ask(I18n.t("shared.key_press"))
168
+ return legends
169
+ end
170
+
171
+ hs = Aromancer::Storage.get_preference(:hide_sentences, default: true)
172
+ hs_value = "#{hs ? "" : "hide_"}signed_sentences".to_sym
173
+ choices = [
174
+ {name: I18n.t("routes.legend.unspoken_words"), value: :words},
175
+ {name: I18n.t("routes.legend.spoken_words"), value: :spoken_words},
176
+ {name: I18n.t("routes.legend.unsigned_sentences"), value: :unsigned_sentences},
177
+ {name: I18n.t("routes.legend.#{hs_value}"), value: hs_value},
178
+ {name: I18n.t("routes.stream.title"), value: :stream},
179
+ {name: I18n.t("routes.main_menu.title"), value: :main_menu}
180
+ ]
181
+ text = ""#Aromancer.get_font(I18n.t("routes.legend_menu.title")).join("\n") +
182
+ "\n#{I18n.t("routes.legend_menu.subtitle")}"
183
+ case Aromancer::Prompt.p.select(text, choices, help: I18n.t("routes.legend_menu.help"), show_help: :always, cycle: true, per_page: 11)
184
+ when :words
185
+ words
186
+ when :spoken_words
187
+ spoken_words
188
+ when :unsigned_sentences
189
+ unsigned_sentences
190
+ when hs_value
191
+ Aromancer::Storage.set_preference(:hide_sentences, !hs)
192
+ legend_menu
193
+ when :stream
194
+ stream
195
+ when :main_menu
196
+ Aromancer::Api.set_active_legend_id(nil)
197
+ main_menu
198
+ end
199
+ end
200
+
201
+ def self.legend
202
+ Aromancer::Prompt.say(I18n.t("shared.navigate", route: :legend))
203
+ Aromancer::Api.load_arena
204
+ arena = arena_data
205
+
206
+ # puts arena.to_json
207
+ turn_player = arena["turn_player"]
208
+
209
+ # title
210
+ Aromancer::Prompt.say("\n\n")
211
+ data = [
212
+ [arena["title"]],
213
+ ["#{
214
+ turn_player["id"] == Aromancer::Storage.get_player["id"] ?
215
+ "your" :
216
+ "#{turn_player["alias"]}'s"
217
+ } turn"],
218
+ ["dealer is #{arena["dealer"]["alias"]}"]
219
+ ]
220
+ title_table = TTY::Table.new(data)
221
+ Aromancer::Prompt.say(title_table.render(:ascii))
222
+
223
+ # players
224
+ data = [
225
+ [I18n.t("routes.legend.players")] + arena["players"].map{|p| p["alias"]}
226
+ ]
227
+ players_table = TTY::Table.new(data)
228
+ Aromancer::Prompt.say(players_table.render(:ascii))
229
+
230
+ # spoken words
231
+ Aromancer::Prompt.say(I18n.t("routes.legend.spoken_words"))
232
+ data = [
233
+ arena["scroll_words"].map{|sw| sw["value_display"]}
234
+ ]
235
+ spoken_words_table = TTY::Table.new(data)
236
+ Aromancer::Prompt.say(spoken_words_table.render(:unicode))
237
+
238
+ unless arena["sentences"].empty?
239
+ # unsigned sentences
240
+ Aromancer::Prompt.say(I18n.t("routes.legend.unsigned_sentences"))
241
+ data = [
242
+ arena["sentences"].map{|sw| "#{sw["value"]} (#{sw["words"].map{|w| w["value_display"]}.sort.join(", ")})"}
243
+ ]
244
+ unsigned_sentences_table = TTY::Table.new(data)
245
+ Aromancer::Prompt.say(unsigned_sentences_table.render(:unicode))
246
+ end
247
+
248
+ # unspoken words
249
+ Aromancer::Prompt.say(I18n.t("routes.legend.unspoken_words"))
250
+ data = [
251
+ arena["player"]["words"].map{|w| w["value_display"]}
252
+ ]
253
+ words_table = TTY::Table.new(data)
254
+ Aromancer::Prompt.say(words_table.render(:ascii))
255
+
256
+ unless arena["player"]["sentences"].empty? || Aromancer::Storage.get_preference(:hide_sentences, default: true)
257
+ # signed sentences
258
+ Aromancer::Prompt.say(I18n.t("routes.legend.signed_sentences"))
259
+ data = [
260
+ arena["player"]["sentences"].map{|s|
261
+ "#{s["value"]}: " + (
262
+ [s["signature"]["value_display"]] + s["words"].map{|w|
263
+ w["value_display"]
264
+ }
265
+ ).join(", ")
266
+ }
267
+ ]
268
+ sentences_table = TTY::Table.new(data)
269
+ Aromancer::Prompt.say(sentences_table.render(:ascii))
270
+ end
271
+ end
272
+
273
+ def self.words
274
+ cls
275
+ legend
276
+
277
+ arena = arena_data
278
+ choices = [{name: :back, value: :back}] + arena["player"]["words"].map{|w| {name: w["value_display"], value: w["id"]}}
279
+ selected_word_id = Aromancer::Prompt.p.select("", choices, show_help: :always, cycle: true, per_page: 11)
280
+
281
+ if selected_word_id == :back
282
+ return legend_menu
283
+ end
284
+
285
+ word(selected_word_id)
286
+ end
287
+
288
+ def self.word(selected_word_id)
289
+ return legend_menu if selected_word_id.nil?
290
+
291
+ Aromancer::Prompt.say(I18n.t("shared.navigate", route: :word))
292
+ possibilities = Aromancer::Api.load_word_possibilities(selected_word_id)
293
+
294
+ # todo: hide/show this
295
+ puts JSON.pretty_generate possibilities
296
+
297
+ options = possibilities["options"]
298
+ selected_word = possibilities["word"]
299
+ for_type = possibilities["for_type"].to_sym
300
+
301
+ arena = arena_data
302
+ player_words = arena["player"]["words"]
303
+
304
+ option_display = Proc.new{|o, sw|
305
+ a = o["action"].humanize.downcase
306
+ o_value = ""
307
+ o_value_display = ""
308
+ if o["sentence"].nil?
309
+ o_value = o["word"]["value"]
310
+ o_value_display = o["word"]["value_display"]
311
+ else
312
+ o_value = o["sentence"]["value"]
313
+ o_value_display = "#{o_value} (#{I18n.t("routes.legend.sentences")})"
314
+ end
315
+ # todo: this sucks
316
+ # case a
317
+ # when :can_sign
318
+ # when :can_combine
319
+ # when :can_stack
320
+ # end
321
+ calc = "(#{sw["value"]} + #{o_value} = #{sw["value"] + o_value})"
322
+
323
+ "#{sw["value_display"]} #{a} #{o_value_display} #{calc}"
324
+ }
325
+
326
+ choices = [
327
+ {name: :back, value: :back}
328
+ ]
329
+ if for_type == :player_word
330
+ # show place on scroll option if selected word is from player's words
331
+ choices << {name: I18n.t("routes.legend.place_on_scroll", word: selected_word["value_display"]), value: :player_word}
332
+ end
333
+ choices += options.map{|o| {name: option_display.call(o, selected_word), value: o}}
334
+ selected_option = Aromancer::Prompt.p.select(
335
+ I18n.t("routes.legend.options_for_word", word: selected_word["value_display"]),
336
+ choices,
337
+ show_help: :always, cycle: true, per_page: 11
338
+ )
339
+
340
+ if selected_option == :back
341
+ return case for_type
342
+ when :player_word
343
+ words
344
+ when :scroll_word
345
+ spoken_words
346
+ when :scroll_sentence
347
+ unsigned_sentences
348
+ end
349
+ elsif selected_option == :player_word
350
+ wytyd = I18n.t("routes.legend.place_on_scroll", word: selected_word["value_display"])
351
+ Aromancer::Prompt.say(wytyd)
352
+ Aromancer::Api.create_turn({
353
+ wytyd: wytyd,
354
+ word_id: selected_word["id"]
355
+ })
356
+ legend_menu
357
+ else
358
+ if selected_option["http_verb"] == "post"
359
+ Aromancer::Api.create_turn(JSON.parse(selected_option["payload"]))
360
+ else
361
+ Aromancer::Api.update_turn(JSON.parse(selected_option["payload"]))
362
+ end
363
+
364
+ legend_menu
365
+ end
366
+ end
367
+
368
+ def self.spoken_words
369
+ cls
370
+ legend
371
+
372
+ arena = arena_data
373
+ choices = [{name: :back, value: :back}] + arena["scroll_words"].map{|w| {name: w["value_display"], value: w["id"]}}
374
+ selected_word_id = Aromancer::Prompt.p.select(I18n.t("routes.legend.spoken_words"), choices, show_help: :always, cycle: true, per_page: 11)
375
+
376
+ if selected_word_id == :back
377
+ return legend_menu
378
+ end
379
+
380
+ word(selected_word_id)
381
+ end
382
+
383
+ def self.unsigned_sentences
384
+ cls
385
+ legend
386
+
387
+ arena = arena_data
388
+ choices = [{name: :back, value: :back}] + arena["sentences"].map{|s| {name: "id: #{s["id"]}, value: #{s["value"]}", value: s}}
389
+ selected_sentence = Aromancer::Prompt.p.select(I18n.t("routes.legend.unsigned_sentences"), choices, show_help: :always, cycle: true, per_page: 11)
390
+
391
+ if selected_sentence == :back
392
+ return legend_menu
393
+ end
394
+
395
+ return legend_menu if selected_sentence.nil?
396
+ ss_words = selected_sentence["words"]
397
+ return legend_menu if ss_words.nil? || ss_words.empty?
398
+
399
+ word(selected_sentence["words"].first["id"])
400
+ end
401
+
402
+ def self.arena_data
403
+ arena = Aromancer::Storage.get_arena
404
+ if arena.nil?
405
+ Aromancer.print_last_error("routes.legend.arena_failed")
406
+ Aromancer::Api.set_active_legend_id(nil)
407
+ main_menu
408
+ else
409
+ arena
410
+ end
411
+ end
412
+
413
+ end
414
+ end
@@ -0,0 +1,190 @@
1
+ # frozen_string_literal: true
2
+
3
+ =begin
4
+
5
+ server.rb
6
+
7
+ aromancer server interface.
8
+
9
+ by i2097i
10
+
11
+ =end
12
+
13
+ module Aromancer
14
+ class Server
15
+ include Singleton
16
+
17
+ SERVER_URL = "http://localhost:3000"
18
+ HEADERS = { "Content-Type": "application/json" }
19
+
20
+ class InternalError
21
+ attr_accessor :status, :body
22
+
23
+ def initialize(status: -1, body: {})
24
+ @status = status
25
+ @body = body
26
+ end
27
+
28
+ def self.build(e)
29
+ InternalError.new(
30
+ status: -1,
31
+ body: {error_message: e.message[0..78]}.to_json
32
+ )
33
+ end
34
+ end
35
+
36
+ def self.api_key_param
37
+ {
38
+ api_key: Aromancer::Storage.get_player["api_key"]
39
+ }
40
+ end
41
+
42
+ def self.sign_in(email_address, password)
43
+ begin
44
+ Faraday.new(
45
+ url: SERVER_URL,
46
+ headers: HEADERS,
47
+ params: {
48
+ email_address: email_address,
49
+ password: password
50
+ }
51
+ ).post("/session")
52
+ rescue StandardError => e
53
+ InternalError.build(e)
54
+ end
55
+ end
56
+
57
+ def self.sign_up(email_address, password, password_confirmation)
58
+ begin
59
+ Faraday.new(
60
+ url: SERVER_URL,
61
+ headers: HEADERS,
62
+ params: {
63
+ user: {
64
+ email_address: email_address,
65
+ password: password,
66
+ password_confirmation: password_confirmation
67
+ }
68
+ }
69
+ ).post("/users")
70
+ rescue StandardError => e
71
+ InternalError.build(e)
72
+ end
73
+ end
74
+
75
+ def self.sign_out
76
+ begin
77
+ Faraday.new(
78
+ url: SERVER_URL,
79
+ headers: HEADERS,
80
+ params: api_key_param
81
+ ).delete("/session")
82
+ rescue StandardError => e
83
+ InternalError.build(e)
84
+ end
85
+ end
86
+
87
+ def self.create_legend(params)
88
+ begin
89
+ Faraday.new(
90
+ url: SERVER_URL,
91
+ headers: HEADERS,
92
+ params: params.merge(api_key_param)
93
+ ).post("/legends")
94
+ rescue StandardError => e
95
+ InternalError.build(e)
96
+ end
97
+ end
98
+
99
+ def self.get_legends
100
+ begin
101
+ Faraday.new(
102
+ url: SERVER_URL,
103
+ headers: HEADERS,
104
+ params: api_key_param
105
+ ).get("/legends")
106
+ rescue StandardError => e
107
+ InternalError.build(e)
108
+ end
109
+ end
110
+
111
+ def self.update_player(params)
112
+ begin
113
+ Faraday.new(
114
+ url: SERVER_URL,
115
+ headers: HEADERS,
116
+ params: params.merge(api_key_param)
117
+ ).put("/players/#{Aromancer::Storage.get_player["id"]}")
118
+ rescue StandardError => e
119
+ InternalError.build(e)
120
+ end
121
+ end
122
+
123
+ def self.get_arena
124
+ legend_id = Aromancer::Storage.get_player["active_legend_id"]
125
+
126
+ begin
127
+ Faraday.new(
128
+ url: SERVER_URL,
129
+ headers: HEADERS,
130
+ params: api_key_param
131
+ ).get("/legends/#{legend_id}/arena")
132
+ rescue StandardError => e
133
+ InternalError.build(e)
134
+ end
135
+ end
136
+
137
+ def self.get_stream
138
+ legend_id = Aromancer::Storage.get_player["active_legend_id"]
139
+
140
+ begin
141
+ Faraday.new(
142
+ url: SERVER_URL,
143
+ headers: HEADERS,
144
+ params: api_key_param
145
+ ).get("/legends/#{legend_id}/stream")
146
+ rescue StandardError => e
147
+ InternalError.build(e)
148
+ end
149
+ end
150
+
151
+ def self.get_word_possibilities(selected_word_id)
152
+ legend_id = Aromancer::Storage.get_player["active_legend_id"]
153
+ begin
154
+ Faraday.new(
155
+ url: SERVER_URL,
156
+ headers: HEADERS,
157
+ params: api_key_param
158
+ ).get("/legends/#{legend_id}/words/#{selected_word_id}/possibilities")
159
+ rescue StandardError => e
160
+ InternalError.build(e)
161
+ end
162
+ end
163
+
164
+ def self.create_turn(params)
165
+ legend_id = Aromancer::Storage.get_player["active_legend_id"]
166
+ begin
167
+ Faraday.new(
168
+ url: SERVER_URL,
169
+ headers: HEADERS,
170
+ params: params.merge(api_key_param)
171
+ ).post("/legends/#{legend_id}/arena")
172
+ rescue StandardError => e
173
+ InternalError.build(e)
174
+ end
175
+ end
176
+
177
+ def self.update_turn(params)
178
+ legend_id = Aromancer::Storage.get_player["active_legend_id"]
179
+ begin
180
+ Faraday.new(
181
+ url: SERVER_URL,
182
+ headers: HEADERS,
183
+ params: params.merge(api_key_param)
184
+ ).put("/legends/#{legend_id}/arena")
185
+ rescue StandardError => e
186
+ InternalError.build(e)
187
+ end
188
+ end
189
+ end
190
+ end