aromancer 0.0.5 → 0.0.6

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.
@@ -14,8 +14,6 @@ module Aromancer
14
14
  class Server
15
15
  include Singleton
16
16
 
17
- DEVELOP_SERVER_URL = "http://localhost:3000"
18
-
19
17
  HEADERS = { "Content-Type": "application/json" }
20
18
 
21
19
  class InternalError
@@ -35,10 +33,8 @@ module Aromancer
35
33
  end
36
34
  end
37
35
 
38
- def self.api_key_param
39
- {
40
- api_key: Aromancer::Storage.get_player["api_key"]
41
- }
36
+ def self.auth_header
37
+ {"Authorization": "Bearer #{Aromancer::Storage.get_player["api_key"]}"}
42
38
  end
43
39
 
44
40
  def self.sign_in(email_address, password)
@@ -78,8 +74,7 @@ module Aromancer
78
74
  begin
79
75
  Faraday.new(
80
76
  url: Aromancer::Storage.get_server_url,
81
- headers: HEADERS,
82
- params: api_key_param
77
+ headers: HEADERS.merge(auth_header),
83
78
  ).delete("/session")
84
79
  rescue StandardError => e
85
80
  InternalError.build(e)
@@ -90,8 +85,8 @@ module Aromancer
90
85
  begin
91
86
  Faraday.new(
92
87
  url: Aromancer::Storage.get_server_url,
93
- headers: HEADERS,
94
- params: params.merge(api_key_param)
88
+ headers: HEADERS.merge(auth_header),
89
+ params: params
95
90
  ).post("/legends")
96
91
  rescue StandardError => e
97
92
  InternalError.build(e)
@@ -102,20 +97,30 @@ module Aromancer
102
97
  begin
103
98
  Faraday.new(
104
99
  url: Aromancer::Storage.get_server_url,
105
- headers: HEADERS,
106
- params: api_key_param
100
+ headers: HEADERS.merge(auth_header),
107
101
  ).get("/legends")
108
102
  rescue StandardError => e
109
103
  InternalError.build(e)
110
104
  end
111
105
  end
112
106
 
107
+ def self.find_legends
108
+ begin
109
+ Faraday.new(
110
+ url: Aromancer::Storage.get_server_url,
111
+ headers: HEADERS.merge(auth_header),
112
+ ).get("/legends/find")
113
+ rescue StandardError => e
114
+ InternalError.build(e)
115
+ end
116
+ end
117
+
113
118
  def self.update_player(params)
114
119
  begin
115
120
  Faraday.new(
116
121
  url: Aromancer::Storage.get_server_url,
117
- headers: HEADERS,
118
- params: params.merge(api_key_param)
122
+ headers: HEADERS.merge(auth_header),
123
+ params: params
119
124
  ).put("/players/#{Aromancer::Storage.get_player["id"]}")
120
125
  rescue StandardError => e
121
126
  InternalError.build(e)
@@ -123,13 +128,13 @@ module Aromancer
123
128
  end
124
129
 
125
130
  def self.get_arena
126
- legend_id = Aromancer::Storage.get_player["active_legend_id"]
131
+ legend_id = (Aromancer::Storage.get_player || {})["active_legend_id"]
132
+ return InternalError.build(StandardError.new("no active legend")) if legend_id.nil?
127
133
 
128
134
  begin
129
135
  Faraday.new(
130
136
  url: Aromancer::Storage.get_server_url,
131
- headers: HEADERS,
132
- params: api_key_param
137
+ headers: HEADERS.merge(auth_header),
133
138
  ).get("/legends/#{legend_id}/arena")
134
139
  rescue StandardError => e
135
140
  InternalError.build(e)
@@ -137,13 +142,13 @@ module Aromancer
137
142
  end
138
143
 
139
144
  def self.get_stream
140
- legend_id = Aromancer::Storage.get_player["active_legend_id"]
145
+ legend_id = (Aromancer::Storage.get_player || {})["active_legend_id"]
146
+ return InternalError.build(StandardError.new("no active legend")) if legend_id.nil?
141
147
 
142
148
  begin
143
149
  Faraday.new(
144
150
  url: Aromancer::Storage.get_server_url,
145
- headers: HEADERS,
146
- params: api_key_param
151
+ headers: HEADERS.merge(auth_header),
147
152
  ).get("/legends/#{legend_id}/stream")
148
153
  rescue StandardError => e
149
154
  InternalError.build(e)
@@ -151,12 +156,13 @@ module Aromancer
151
156
  end
152
157
 
153
158
  def self.get_word_possibilities(selected_word_id)
154
- legend_id = Aromancer::Storage.get_player["active_legend_id"]
159
+ legend_id = (Aromancer::Storage.get_player || {})["active_legend_id"]
160
+ return InternalError.build(StandardError.new("no active legend")) if legend_id.nil?
161
+
155
162
  begin
156
163
  Faraday.new(
157
164
  url: Aromancer::Storage.get_server_url,
158
- headers: HEADERS,
159
- params: api_key_param
165
+ headers: HEADERS.merge(auth_header),
160
166
  ).get("/legends/#{legend_id}/words/#{selected_word_id}/possibilities")
161
167
  rescue StandardError => e
162
168
  InternalError.build(e)
@@ -164,12 +170,14 @@ module Aromancer
164
170
  end
165
171
 
166
172
  def self.create_turn(params)
167
- legend_id = Aromancer::Storage.get_player["active_legend_id"]
173
+ legend_id = (Aromancer::Storage.get_player || {})["active_legend_id"]
174
+ return InternalError.build(StandardError.new("no active legend")) if legend_id.nil?
175
+
168
176
  begin
169
177
  Faraday.new(
170
178
  url: Aromancer::Storage.get_server_url,
171
- headers: HEADERS,
172
- params: params.merge(api_key_param)
179
+ headers: HEADERS.merge(auth_header),
180
+ params: params
173
181
  ).post("/legends/#{legend_id}/arena")
174
182
  rescue StandardError => e
175
183
  InternalError.build(e)
@@ -177,12 +185,14 @@ module Aromancer
177
185
  end
178
186
 
179
187
  def self.update_turn(params)
180
- legend_id = Aromancer::Storage.get_player["active_legend_id"]
188
+ legend_id = (Aromancer::Storage.get_player || {})["active_legend_id"]
189
+ return InternalError.build(StandardError.new("no active legend")) if legend_id.nil?
190
+
181
191
  begin
182
192
  Faraday.new(
183
193
  url: Aromancer::Storage.get_server_url,
184
- headers: HEADERS,
185
- params: params.merge(api_key_param)
194
+ headers: HEADERS.merge(auth_header),
195
+ params: params
186
196
  ).put("/legends/#{legend_id}/arena")
187
197
  rescue StandardError => e
188
198
  InternalError.build(e)
@@ -12,6 +12,8 @@ module Aromancer
12
12
  class Storage
13
13
  include Singleton
14
14
 
15
+ DEFAULT_SERVER = "http://aromancer.com"
16
+
15
17
  attr_accessor :storage_open, :cache
16
18
 
17
19
  def initialize
@@ -61,8 +63,12 @@ module Aromancer
61
63
  instance.set_key(p_key, value)
62
64
  end
63
65
 
66
+ def self.toggle_preference(key)
67
+ set_preference(key, !get_preference(key))
68
+ end
69
+
64
70
  def self.toggle_force_ssl
65
- set_preference(:force_ssl, !get_preference(:force_ssl))
71
+ toggle_preference(:force_ssl)
66
72
  v = get_preference(:force_ssl)
67
73
  self.instance.set_key(:server_url_scheme, "http#{v ? :s : ""}")
68
74
  self.instance.set_key(:websocket_scheme, "ws#{v ? :s : ""}")
@@ -126,15 +132,16 @@ module Aromancer
126
132
  uri = URI.parse(server_url)
127
133
  if uri.kind_of?(URI::HTTP) or uri.kind_of?(URI::HTTPS)
128
134
  URI_KEYS.each{|k|
135
+ uri.kind_of?(URI::HTTP) && get_preference(:force_ssl) ? toggle_force_ssl : nil
129
136
  Aromancer::Storage.instance.set_key("server_url_#{k}", uri.select(k).first)
130
137
  }
131
- else
132
- set_server_url(Aromancer::Server::DEVELOP_SERVER_URL)
138
+ elsif get_server_url.nil?
139
+ set_server_url(DEFAULT_SERVER)
133
140
  end
134
141
  end
135
142
 
136
143
  def self.get_server_url
137
- set_server_url(Aromancer::Server::DEVELOP_SERVER_URL) if URI_KEYS.all?{|k| Aromancer::Storage.instance.get_key("server_url_#{k}").nil?}
144
+ set_server_url(DEFAULT_SERVER) if URI_KEYS.all?{|k| Aromancer::Storage.instance.get_key("server_url_#{k}").nil?}
138
145
  URI.parse(URI_KEYS.map{|k|
139
146
  c = Aromancer::Storage.instance.get_key("server_url_#{k}")
140
147
  case k
@@ -187,16 +194,15 @@ module Aromancer
187
194
  FileUtils.rm(Aromancer::Storage.storage_filepath)
188
195
  return
189
196
  end
190
- @storage_open = false
191
197
 
192
198
  # only update the cache value if present in storage
193
199
  if storage_contents.keys.include?(key)
194
- @cache[key][:value] = storage_contents[key]
195
- @cache[key][:persisted] = true
200
+ @cache[key] = {value: storage_contents[key], persisted: true}
196
201
  else
197
202
  @cache[key][:persisted] = false
198
203
  end
199
204
 
205
+ @storage_open = false
200
206
  @cache[key][:value]
201
207
  end
202
208
 
@@ -11,5 +11,5 @@
11
11
  =end
12
12
 
13
13
  module Aromancer
14
- VERSION = "0.0.5"
14
+ VERSION = "0.0.6"
15
15
  end
@@ -16,14 +16,22 @@ module Aromancer
16
16
 
17
17
  TYPES = [
18
18
  :arena,
19
- :player
19
+ :legends,
20
+ :player # todo: not used
20
21
  ]
21
22
 
22
23
  attr_accessor :socket
23
24
 
24
- def connect(api_key)
25
+ def connect
25
26
  return unless self.socket.nil?
26
- self.socket = WebSocket::Client::Simple.connect("#{Aromancer::Storage.get_websocket_url}?api_key=#{api_key}")
27
+ return if Aromancer::Storage.get_player["api_key"].nil?
28
+
29
+ begin
30
+ self.socket = WebSocket::Client::Simple.connect(Aromancer::Storage.get_websocket_url, {headers: Aromancer::Server.auth_header})
31
+ rescue Socket::ResolutionError => e
32
+ disconnect
33
+ return
34
+ end
27
35
  self.socket.on :message do |msg|
28
36
  payload = JSON.parse(msg.data) rescue msg.data
29
37
  if !payload.nil? &&
@@ -32,10 +40,18 @@ module Aromancer
32
40
  !payload["message"]["type"].nil? &&
33
41
  TYPES.include?(payload["message"]["type"].to_sym)
34
42
 
35
- legend_id = payload["message"]["id"]
36
- lid = Aromancer::Storage.get_player&.symbolize_keys[:active_legend_id]
37
- if !lid.nil? && lid == legend_id.to_i
38
- Aromancer::Cli.instance.start_ui_thread
43
+ case payload["message"]["type"].to_sym
44
+ when :arena
45
+ legend_id = payload["message"]["id"]
46
+ lid = Aromancer::Storage.get_player&.symbolize_keys[:active_legend_id]
47
+ if !lid.nil? && lid == legend_id.to_i
48
+ Aromancer::Api.load_arena
49
+ sleep(0.5)
50
+ Aromancer::Cli.instance.start_ui_thread
51
+ end
52
+ when :legends
53
+ Aromancer::Api.get_legends
54
+ when :player
39
55
  end
40
56
  end
41
57
  end
@@ -43,7 +59,7 @@ module Aromancer
43
59
  self.socket.on :open do
44
60
  r = {
45
61
  command: "subscribe",
46
- identifier: {channel: "PlayerChannel", api_key: api_key}.to_json
62
+ identifier: {channel: "PlayerChannel"}.to_json
47
63
  }.to_json
48
64
  Aromancer::Websocket.instance.socket.send(r)
49
65
  end
@@ -59,7 +75,8 @@ module Aromancer
59
75
  end
60
76
 
61
77
  def disconnect
62
- self.socket = nil unless self.socket.nil?
78
+ self.socket&.close
79
+ self.socket = nil
63
80
  end
64
81
  end
65
82
  end
data/lib/aromancer.rb CHANGED
@@ -14,9 +14,14 @@ require_relative :reiquire.to_s
14
14
  Reiquire::aromancer
15
15
 
16
16
  module Aromancer
17
- THROTTLE_MS = 0.4
17
+ THROTTLE_MS = 0.2
18
18
  FONT = TTY::Font.new(:standard)
19
19
 
20
+ UNICODE = {
21
+ close: "\u2A2F",
22
+ check: "\u2713"
23
+ }
24
+
20
25
  # instance runs on main thread
21
26
  class Cli
22
27
  include Singleton
@@ -25,8 +30,18 @@ module Aromancer
25
30
 
26
31
  # user entry point
27
32
  def self.run
33
+ # ensure preferences exist
34
+ Aromancer::Storage.get_preference(:debug, default: false)
35
+ Aromancer::Storage.get_preference(:force_ssl, default: true)
36
+ Aromancer::Storage.get_preference(:hide_sentences, default: true)
37
+
38
+ self.instance.last_render = 0
39
+
40
+ # load player on-start
41
+ Aromancer::Api.set_active_legend_id(nil) unless Aromancer::Storage.get_player.nil?
42
+
28
43
  Thread.main[:route] = :authentication
29
- self.instance.last_render = Time.now
44
+ Thread.main[:menu_options] = {}
30
45
  Aromancer::Prompt.say(I18n.t("shared.welcome", version: Aromancer::VERSION))
31
46
  Aromancer::Prompt.say(I18n.t("shared.server_url", url: Aromancer::Storage::get_server_url))
32
47
  self.instance.start_ui_thread
@@ -35,7 +50,13 @@ module Aromancer
35
50
  begin
36
51
  self.instance.ui_thread.join
37
52
  rescue NoMethodError => e
53
+ if Aromancer::Storage.get_preference(:debug)
54
+ Aromancer::Prompt.say(I18n.t("shared.last_error"))
55
+ Aromancer::Prompt.say(e.inspect)
56
+ sleep(5)
57
+ end
38
58
  self.instance.start_ui_thread
59
+ self.instance.start_ws_thread
39
60
  sleep(1)
40
61
  rescue Interrupt => e
41
62
  exit
@@ -43,32 +64,29 @@ module Aromancer
43
64
  end
44
65
  end
45
66
 
46
- def start_ui_thread
47
- if @busy || Time.now - @last_render < 2
48
- # Thread.new{
49
- # while Aromancer::Cli.instance.busy do
50
- # if Time.now - Aromancer::Cli.instance.last_render > 5
51
- # sleep(2)
52
- # Aromancer::Cli.instance.start_ui_thread
53
- # end
54
- # end
55
- # }.join
56
- return
57
- end
67
+ def get_view(view_key)
68
+ Thread.main[:menu_options][view_key.to_sym]
69
+ end
70
+
71
+ def start_ui_thread(force = false)
72
+ return if (@busy || Time.now - @last_render < 2) && !force
73
+
58
74
  @busy = true
59
75
  self.ui_thread&.exit
60
76
  self.ui_thread&.kill
61
- Thread.main[:input_controls] = nil
77
+ Thread.main[:menu_runners] = {}
62
78
  Aromancer::Prompt.instance.reload!
63
79
  self.ui_thread = Thread.new do
64
80
  loop do
65
- ic = Thread.main[:input_controls]
66
- unless ic.nil?
81
+ menu_options = Thread.main[:menu_options][Thread.main[:route]]
82
+ menu_runners = Thread.main[:menu_runners][Thread.main[:route]]
83
+ unless menu_options.nil? || menu_runners.nil?
67
84
  Aromancer::Routes.resume
68
85
  sleep(THROTTLE_MS)
69
- v = Aromancer::Prompt.p.select("", ic[:choices], show_help: :always, cycle: true, per_page: 11)
70
- runners = ic[:runners].select{|r| r[:value] == v}
71
- runners = ic[:runners].select{|r| r[:value].nil?} if runners.empty?
86
+ Aromancer.print_hud
87
+ v = Aromancer::Prompt.p.select("", menu_options, show_help: :always, cycle: true, per_page: 11)
88
+ runners = menu_runners.select{|r| r[:value] == v}
89
+ runners = menu_runners.select{|r| r[:value].nil?} if runners.empty?
72
90
 
73
91
  if runners.any?
74
92
  r = runners.first
@@ -89,14 +107,14 @@ module Aromancer
89
107
  def start_ws_thread
90
108
  self.ws_thread.kill unless self.ws_thread.nil?
91
109
  self.ws_thread = Thread.new do
110
+ Aromancer::Websocket.instance.disconnect
92
111
  loop do
93
112
  player = Aromancer::Storage.get_player
94
113
  if player.nil?
95
114
  Aromancer::Websocket.instance.disconnect
96
115
  elsif !player["api_key"].nil?
97
116
  # attempt websocket connection
98
- # puts :ws_thread
99
- Aromancer::Websocket.instance.connect(player["api_key"])
117
+ Aromancer::Websocket.instance.connect
100
118
  end
101
119
 
102
120
  sleep(4)
@@ -114,6 +132,19 @@ module Aromancer
114
132
  "#{`echo $HOME`.strip}/.aromancer"
115
133
  end
116
134
 
135
+ def self.print_hud
136
+ websocket_status = "#{Aromancer::Storage.instance.get_key(:websocket_scheme)}: #{Aromancer::Websocket.instance.socket.nil? ? UNICODE[:close] : UNICODE[:check] }"
137
+ player_status = if Aromancer::Storage.get_player.nil?
138
+ I18n.t("routes.main_menu.not_signed_in")
139
+ else
140
+ I18n.t("shared.signed_in_as", as: Aromancer::Storage.get_player["alias"])
141
+ end
142
+
143
+ Aromancer::Prompt.say(
144
+ [nil, player_status, websocket_status, nil].join(" | ")
145
+ )
146
+ end
147
+
117
148
  def self.print_last_error(i18n_key = nil)
118
149
  last_error = Aromancer::Storage.get_last_error
119
150
  return if last_error.nil?
@@ -125,6 +156,7 @@ module Aromancer
125
156
  rescue JSON::ParserError => e
126
157
  message = last_error[:body]
127
158
  end
128
- Aromancer::Prompt.say(I18n.t(i18n_key, status: last_error[:status], error: message))
159
+ Aromancer::Prompt.say(I18n.t(i18n_key || "shared.last_error", status: last_error[:status], error: message))
160
+ Aromancer::Storage.set_last_error(nil)
129
161
  end
130
162
  end
data/locale/en.yml CHANGED
@@ -11,6 +11,8 @@ en:
11
11
  navigate: "navigate to %{route}."
12
12
  update_cancel: "update cancelled."
13
13
  update_confirm: "confirm update [%{new_value}] (enter y): "
14
+ signed_in_as: "authenticated as %{as}"
15
+ last_error: "error (%{status}). %{error}"
14
16
  back: "back"
15
17
  exit: "exit"
16
18
  routes:
@@ -26,17 +28,20 @@ en:
26
28
  subtitle: ""
27
29
  new_game: "new game"
28
30
  load_game: "load game"
31
+ find_game: "find game"
29
32
  player_count: "enter player count (1-2): "
30
33
  sign_out: "sign out"
31
- not_signed_in: "not signed in. invalid session. redirecting to authentication."
34
+ not_signed_in: "signed out"
32
35
  configure:
33
36
  title: "configure %{name}"
34
37
  new_host: "enter new server host: "
35
38
  new_port: "enter new server port: "
36
- force_ssl_toggle: "force ssl preference toggled to %{value}"
39
+ force_ssl_toggle: "ssl preference toggled to %{value}"
37
40
  server_host: "host (%{stored})"
38
41
  server_port: "port (%{stored})"
39
- force_ssl: "force ssl (%{stored})"
42
+ force_ssl: "ssl (%{stored})"
43
+ debug: "debug (%{stored})"
44
+ debug_toggle: "debug preference toggled to %{value}"
40
45
  new_game:
41
46
  player_count: "number of players"
42
47
  story_count: "number of stories"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aromancer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - i2097i
@@ -245,6 +245,7 @@ files:
245
245
  - checksums/aromancer-0.0.3.gem.sha512
246
246
  - checksums/aromancer-0.0.4.gem.sha512
247
247
  - checksums/aromancer-0.0.5.gem.sha512
248
+ - checksums/aromancer-0.0.6.gem.sha512
248
249
  - gem_graph.png
249
250
  - lib/aromancer.rb
250
251
  - lib/aromancer/.DS_Store