story_key 0.4.0 → 0.5.0
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/.ruby-version +1 -1
- data/Gemfile +1 -2
- data/Gemfile.lock +100 -72
- data/README.md +7 -9
- data/Rakefile +0 -1
- data/bin/console +0 -1
- data/examples/card.png +0 -0
- data/examples/cli.png +0 -0
- data/lib/story_key/base.rb +0 -1
- data/lib/story_key/class_methods.rb +2 -3
- data/lib/story_key/coercer.rb +2 -3
- data/lib/story_key/console/recover.rb +17 -18
- data/lib/story_key/console.rb +33 -31
- data/lib/story_key/data.rb +0 -1
- data/lib/story_key/decoder.rb +5 -6
- data/lib/story_key/encoder.rb +19 -18
- data/lib/story_key/image_generator.rb +43 -26
- data/lib/story_key/key_generator.rb +3 -4
- data/lib/story_key/lexicon.rb +1 -2
- data/lib/story_key/tokenizer.rb +3 -4
- data/lib/story_key/version.rb +3 -4
- data/lib/story_key.rb +15 -16
- data/rakelib/lexicon.rake +0 -2
- data/story_key.gemspec +29 -30
- metadata +48 -46
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: be2facdf65cadfc79be9b3277589e6ee1b39eccb900e69f6f68925f773007422
|
|
4
|
+
data.tar.gz: 86611058f31408ed45947210e5d694fbb08a9323edbe4290b4d30fdbed0f662d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a66c4b2d31b047c2de09900525c11dfbb66d186c11ad35bcdccff88b156ec07bec7afeb33789aeac394ed74fc309f143d0aac2d67c3a053f597b5e5cf1386860
|
|
7
|
+
data.tar.gz: 68e554476c0586267972deadaa8833d999747f4821604f9f95dc5aa18285d19a5e38b3090b008f50c601569975feb69a47ab5cfd9235183bdf2ee4ef08b445e4
|
data/.rubocop.yml
CHANGED
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
3.
|
|
1
|
+
3.3.0
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,119 +1,147 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
story_key (0.
|
|
5
|
-
activesupport (~>
|
|
4
|
+
story_key (0.5.0)
|
|
5
|
+
activesupport (~> 8.0.1)
|
|
6
6
|
awesome_print (~> 1.9.2)
|
|
7
7
|
base58 (~> 0.2.3)
|
|
8
|
-
dotenv (~>
|
|
8
|
+
dotenv (~> 3.1.6)
|
|
9
9
|
dry-initializer (~> 3.1.1)
|
|
10
10
|
indefinite_article (~> 0.2.5)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
zeitwerk (~> 2.6.6)
|
|
11
|
+
remedy (~> 0.4.0)
|
|
12
|
+
rmagick (~> 6.0.1)
|
|
13
|
+
thor (~> 1.3.2)
|
|
14
|
+
typhoeus (~> 1.4.1)
|
|
15
|
+
zeitwerk (~> 2.7.1)
|
|
17
16
|
|
|
18
17
|
GEM
|
|
19
18
|
remote: https://rubygems.org/
|
|
20
19
|
specs:
|
|
21
|
-
activesupport (
|
|
22
|
-
|
|
20
|
+
activesupport (8.0.1)
|
|
21
|
+
base64
|
|
22
|
+
benchmark (>= 0.3)
|
|
23
|
+
bigdecimal
|
|
24
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
25
|
+
connection_pool (>= 2.2.5)
|
|
26
|
+
drb
|
|
23
27
|
i18n (>= 1.6, < 2)
|
|
28
|
+
logger (>= 1.4.2)
|
|
24
29
|
minitest (>= 5.1)
|
|
25
|
-
|
|
30
|
+
securerandom (>= 0.3)
|
|
31
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
32
|
+
uri (>= 0.13.1)
|
|
26
33
|
ast (2.4.2)
|
|
27
34
|
awesome_print (1.9.2)
|
|
28
35
|
base58 (0.2.3)
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
36
|
+
base64 (0.2.0)
|
|
37
|
+
benchmark (0.4.0)
|
|
38
|
+
bigdecimal (3.1.8)
|
|
39
|
+
concurrent-ruby (1.3.4)
|
|
40
|
+
connection_pool (2.4.1)
|
|
41
|
+
diff-lcs (1.5.1)
|
|
42
|
+
dotenv (3.1.6)
|
|
43
|
+
drb (2.2.1)
|
|
33
44
|
dry-initializer (3.1.1)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
45
|
+
ethon (0.16.0)
|
|
46
|
+
ffi (>= 1.15.0)
|
|
47
|
+
ffi (1.17.0-arm64-darwin)
|
|
37
48
|
i18n (1.12.0)
|
|
38
49
|
concurrent-ruby (~> 1.0)
|
|
39
50
|
indefinite_article (0.2.5)
|
|
40
51
|
activesupport
|
|
41
|
-
json (2.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
mime-types-data (~> 3.2015)
|
|
45
|
-
mime-types-data (3.2022.0105)
|
|
52
|
+
json (2.9.0)
|
|
53
|
+
language_server-protocol (3.17.0.3)
|
|
54
|
+
logger (1.6.3)
|
|
46
55
|
minitest (5.16.3)
|
|
47
|
-
|
|
48
|
-
parallel (1.
|
|
49
|
-
parser (3.
|
|
56
|
+
observer (0.1.2)
|
|
57
|
+
parallel (1.26.3)
|
|
58
|
+
parser (3.3.6.0)
|
|
50
59
|
ast (~> 2.4.1)
|
|
60
|
+
racc
|
|
51
61
|
pkg-config (1.5.1)
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
method_source (~> 1.0)
|
|
62
|
+
racc (1.8.1)
|
|
63
|
+
rack (3.1.8)
|
|
55
64
|
rainbow (3.1.1)
|
|
56
|
-
rake (13.
|
|
57
|
-
regexp_parser (2.
|
|
58
|
-
remedy (0.
|
|
59
|
-
|
|
60
|
-
|
|
65
|
+
rake (13.2.1)
|
|
66
|
+
regexp_parser (2.9.3)
|
|
67
|
+
remedy (0.4.0)
|
|
68
|
+
rmagick (6.0.1)
|
|
69
|
+
observer (~> 0.1)
|
|
61
70
|
pkg-config (~> 1.4)
|
|
62
|
-
rspec (3.
|
|
63
|
-
rspec-core (~> 3.
|
|
64
|
-
rspec-expectations (~> 3.
|
|
65
|
-
rspec-mocks (~> 3.
|
|
66
|
-
rspec-core (3.
|
|
67
|
-
rspec-support (~> 3.
|
|
68
|
-
rspec-expectations (3.
|
|
71
|
+
rspec (3.13.0)
|
|
72
|
+
rspec-core (~> 3.13.0)
|
|
73
|
+
rspec-expectations (~> 3.13.0)
|
|
74
|
+
rspec-mocks (~> 3.13.0)
|
|
75
|
+
rspec-core (3.13.2)
|
|
76
|
+
rspec-support (~> 3.13.0)
|
|
77
|
+
rspec-expectations (3.13.3)
|
|
69
78
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
70
|
-
rspec-support (~> 3.
|
|
71
|
-
rspec-mocks (3.
|
|
79
|
+
rspec-support (~> 3.13.0)
|
|
80
|
+
rspec-mocks (3.13.2)
|
|
72
81
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
73
|
-
rspec-support (~> 3.
|
|
74
|
-
rspec-support (3.
|
|
75
|
-
rubocop (1.
|
|
82
|
+
rspec-support (~> 3.13.0)
|
|
83
|
+
rspec-support (3.13.2)
|
|
84
|
+
rubocop (1.69.2)
|
|
76
85
|
json (~> 2.3)
|
|
86
|
+
language_server-protocol (>= 3.17.0)
|
|
77
87
|
parallel (~> 1.10)
|
|
78
|
-
parser (>= 3.
|
|
88
|
+
parser (>= 3.3.0.2)
|
|
79
89
|
rainbow (>= 2.2.2, < 4.0)
|
|
80
|
-
regexp_parser (>=
|
|
81
|
-
|
|
82
|
-
rubocop-ast (>= 1.23.0, < 2.0)
|
|
90
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
91
|
+
rubocop-ast (>= 1.36.2, < 2.0)
|
|
83
92
|
ruby-progressbar (~> 1.7)
|
|
84
|
-
unicode-display_width (>=
|
|
85
|
-
rubocop-ast (1.
|
|
86
|
-
parser (>= 3.
|
|
87
|
-
rubocop-
|
|
88
|
-
rubocop (>= 1.
|
|
89
|
-
rubocop-ast (>=
|
|
93
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
94
|
+
rubocop-ast (1.37.0)
|
|
95
|
+
parser (>= 3.3.1.0)
|
|
96
|
+
rubocop-minitest (0.34.5)
|
|
97
|
+
rubocop (>= 1.39, < 2.0)
|
|
98
|
+
rubocop-ast (>= 1.30.0, < 2.0)
|
|
99
|
+
rubocop-performance (1.23.0)
|
|
100
|
+
rubocop (>= 1.48.1, < 2.0)
|
|
101
|
+
rubocop-ast (>= 1.31.1, < 2.0)
|
|
102
|
+
rubocop-rails (2.25.1)
|
|
103
|
+
activesupport (>= 4.2.0)
|
|
104
|
+
rack (>= 1.1)
|
|
105
|
+
rubocop (>= 1.33.0, < 2.0)
|
|
106
|
+
rubocop-ast (>= 1.31.1, < 2.0)
|
|
107
|
+
rubocop-rails-omakase (1.0.0)
|
|
108
|
+
rubocop
|
|
109
|
+
rubocop-minitest
|
|
110
|
+
rubocop-performance
|
|
111
|
+
rubocop-rails
|
|
90
112
|
rubocop-rake (0.6.0)
|
|
91
113
|
rubocop (~> 1.0)
|
|
92
|
-
rubocop-rspec (
|
|
93
|
-
rubocop (~> 1.
|
|
94
|
-
ruby-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
114
|
+
rubocop-rspec (3.3.0)
|
|
115
|
+
rubocop (~> 1.61)
|
|
116
|
+
ruby-progressbar (1.13.0)
|
|
117
|
+
securerandom (0.4.0)
|
|
118
|
+
thor (1.3.2)
|
|
119
|
+
typhoeus (1.4.1)
|
|
120
|
+
ethon (>= 0.9.0)
|
|
98
121
|
tzinfo (2.0.5)
|
|
99
122
|
concurrent-ruby (~> 1.0)
|
|
100
|
-
unicode-display_width (
|
|
101
|
-
|
|
123
|
+
unicode-display_width (3.1.2)
|
|
124
|
+
unicode-emoji (~> 4.0, >= 4.0.4)
|
|
125
|
+
unicode-emoji (4.0.4)
|
|
126
|
+
uri (1.0.2)
|
|
127
|
+
zeitwerk (2.7.1)
|
|
102
128
|
|
|
103
129
|
PLATFORMS
|
|
104
130
|
arm64-darwin-21
|
|
105
131
|
arm64-darwin-22
|
|
132
|
+
arm64-darwin-23
|
|
106
133
|
x86_64-linux
|
|
107
134
|
|
|
108
135
|
DEPENDENCIES
|
|
109
|
-
bundler (~> 2.
|
|
110
|
-
rake (~> 13.
|
|
111
|
-
rspec (~> 3.
|
|
112
|
-
rubocop (~> 1.
|
|
113
|
-
rubocop-performance (~> 1.
|
|
136
|
+
bundler (~> 2.5.23)
|
|
137
|
+
rake (~> 13.2.1)
|
|
138
|
+
rspec (~> 3.13.0)
|
|
139
|
+
rubocop (~> 1.69.2)
|
|
140
|
+
rubocop-performance (~> 1.23.0)
|
|
141
|
+
rubocop-rails-omakase (~> 1.0.0)
|
|
114
142
|
rubocop-rake (~> 0.6.0)
|
|
115
|
-
rubocop-rspec (~>
|
|
143
|
+
rubocop-rspec (~> 3.3.0)
|
|
116
144
|
story_key!
|
|
117
145
|
|
|
118
146
|
BUNDLED WITH
|
|
119
|
-
2.
|
|
147
|
+
2.5.23
|
data/README.md
CHANGED
|
@@ -1,20 +1,16 @@
|
|
|
1
1
|
[](https://badge.fury.io/rb/story_key)
|
|
2
|
-
[](https://travis-ci.org/jcraigk/story_key)
|
|
3
|
-
[](https://codeclimate.com/github/jcraigk/story_key/maintainability)
|
|
4
2
|
|
|
5
3
|
|
|
6
|
-

|
|
7
|
-
|
|
8
4
|
| Gem Version | Locale | Lexicon SHA |
|
|
9
5
|
|-------------|--------|-------------|
|
|
10
|
-
| 0.
|
|
6
|
+
| 0.5.0 | Miami | 3bfbbf9 |
|
|
11
7
|
|
|
12
8
|
Locale will not change until v1.0 release
|
|
13
9
|
|
|
14
10
|
|
|
15
11
|
# StoryKey
|
|
16
12
|
|
|
17
|
-
StoryKey is a proof of concept [Brainwallet](https://en.bitcoin.it/wiki/Brainwallet) inspired by [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) written in
|
|
13
|
+
StoryKey is a proof of concept [Brainwallet](https://en.bitcoin.it/wiki/Brainwallet) inspired by [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) written in Ruby. It converts an arbitrary string of data, such as a [cryptocurrency private key](https://en.bitcoin.it/wiki/Private_key), into an English paragraph intended for longterm human memory. It also assists in decoding the story back into its original form. Optionally, a visual representation of the paragraph is also provided using [OpenAI DALL-E](https://openai.com/dall-e-3).
|
|
18
14
|
|
|
19
15
|
Each story is provided in multiple formats:
|
|
20
16
|
* Humanized Text
|
|
@@ -27,9 +23,10 @@ Each story is provided in multiple formats:
|
|
|
27
23
|
* Space-delimited lowercase alphanumeric/dash
|
|
28
24
|
* Useful as a seed phrase for generating derivative keys
|
|
29
25
|
* Graphical
|
|
30
|
-
* AI-generated images via [DALL-E](https://openai.com/dall-e-
|
|
26
|
+
* AI-generated images via [DALL-E](https://openai.com/dall-e-3)
|
|
31
27
|
* Requires OpenAI key
|
|
32
28
|
|
|
29
|
+
|
|
33
30
|
## Features
|
|
34
31
|
|
|
35
32
|
* Encodes arbitrary length data from 1 to 512 bits (default 256)
|
|
@@ -53,8 +50,9 @@ Each token of the story, which may be a single word or short compound phrase, en
|
|
|
53
50
|
|
|
54
51
|
An example key with its associated story, seed phrase, and image are shown below.
|
|
55
52
|
|
|
56
|
-

|
|
54
|
+
|
|
55
|
+

|
|
58
56
|
|
|
59
57
|
```
|
|
60
58
|
Key:
|
data/Rakefile
CHANGED
data/bin/console
CHANGED
data/examples/card.png
ADDED
|
Binary file
|
data/examples/cli.png
ADDED
|
Binary file
|
data/lib/story_key/base.rb
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
1
|
module StoryKey::ClassMethods
|
|
3
2
|
def encode(...)
|
|
4
3
|
StoryKey::Encoder.call(...)
|
|
@@ -15,8 +14,8 @@ module StoryKey::ClassMethods
|
|
|
15
14
|
def generate(bitsize: StoryKey::DEFAULT_BITSIZE)
|
|
16
15
|
key = StoryKey::KeyGenerator.call(bitsize:)
|
|
17
16
|
encoded = encode(key:, bitsize:)
|
|
18
|
-
raise
|
|
19
|
-
[key, encoded]
|
|
17
|
+
raise "An error occurred!" if key != decode(story: encoded.text)
|
|
18
|
+
[ key, encoded ]
|
|
20
19
|
end
|
|
21
20
|
end
|
|
22
21
|
|
data/lib/story_key/coercer.rb
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
1
|
class StoryKey::Coercer < StoryKey::Base
|
|
3
2
|
option :str
|
|
4
|
-
option :bitsize, default: -> {}
|
|
3
|
+
option :bitsize, default: -> { }
|
|
5
4
|
option :from
|
|
6
5
|
option :to
|
|
7
6
|
|
|
@@ -12,7 +11,7 @@ class StoryKey::Coercer < StoryKey::Base
|
|
|
12
11
|
private
|
|
13
12
|
|
|
14
13
|
def binary_str
|
|
15
|
-
bitsize ? bin.rjust(bitsize,
|
|
14
|
+
bitsize ? bin.rjust(bitsize, "0") : bin
|
|
16
15
|
end
|
|
17
16
|
|
|
18
17
|
def bin
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
1
|
class StoryKey::Console::Recover < StoryKey::Base
|
|
3
2
|
include Remedy
|
|
4
3
|
|
|
@@ -7,7 +6,7 @@ class StoryKey::Console::Recover < StoryKey::Base
|
|
|
7
6
|
CYAN = 36
|
|
8
7
|
BG_RED = 41
|
|
9
8
|
EXIT_WORD = :control_x
|
|
10
|
-
FRAME_HORIZONTAL =
|
|
9
|
+
FRAME_HORIZONTAL = "─"
|
|
11
10
|
GREEN = 32
|
|
12
11
|
NUM_OPTIONS = 5
|
|
13
12
|
RED = 31
|
|
@@ -17,7 +16,7 @@ class StoryKey::Console::Recover < StoryKey::Base
|
|
|
17
16
|
@option_idx = 0
|
|
18
17
|
clear_options
|
|
19
18
|
clear_user_str
|
|
20
|
-
@prompt =
|
|
19
|
+
@prompt = "Enter word(s): "
|
|
21
20
|
|
|
22
21
|
ask_version_slug
|
|
23
22
|
ask_num_phrases
|
|
@@ -60,7 +59,7 @@ class StoryKey::Console::Recover < StoryKey::Base
|
|
|
60
59
|
end
|
|
61
60
|
|
|
62
61
|
def clear_user_str
|
|
63
|
-
@user_str =
|
|
62
|
+
@user_str = ""
|
|
64
63
|
end
|
|
65
64
|
|
|
66
65
|
def input_backspace
|
|
@@ -78,7 +77,7 @@ class StoryKey::Console::Recover < StoryKey::Base
|
|
|
78
77
|
clear_options
|
|
79
78
|
@entry_idx = -1
|
|
80
79
|
@instructions = decode_story
|
|
81
|
-
@prompt = colorize(
|
|
80
|
+
@prompt = colorize("(press any key to exit)", RED)
|
|
82
81
|
draw
|
|
83
82
|
console.get_key
|
|
84
83
|
quit_console
|
|
@@ -88,7 +87,7 @@ class StoryKey::Console::Recover < StoryKey::Base
|
|
|
88
87
|
key = StoryKey.decode(story: "#{StoryKey::VERSION_SLUG} #{entries.join(' ')}")
|
|
89
88
|
"#{colorize('Key:', BG_BLUE)} #{colorize(key, GREEN)}"
|
|
90
89
|
rescue StoryKey::InvalidChecksum
|
|
91
|
-
colorize(
|
|
90
|
+
colorize("Checksum failed! Invalid story.", BG_RED)
|
|
92
91
|
end
|
|
93
92
|
|
|
94
93
|
def refresh_options
|
|
@@ -125,7 +124,7 @@ class StoryKey::Console::Recover < StoryKey::Base
|
|
|
125
124
|
key = console.get_key
|
|
126
125
|
puts
|
|
127
126
|
return if confirm?(key)
|
|
128
|
-
quit(
|
|
127
|
+
quit("Sorry, this version of StoryKey can't decode your story")
|
|
129
128
|
end
|
|
130
129
|
|
|
131
130
|
def num_parts
|
|
@@ -146,7 +145,7 @@ class StoryKey::Console::Recover < StoryKey::Base
|
|
|
146
145
|
input = gets
|
|
147
146
|
input = default_num_phrases if input.blank?
|
|
148
147
|
@num_phrases = input.to_i.tap do |i|
|
|
149
|
-
quit(
|
|
148
|
+
quit("Invalid number") unless i.in?(1..max_num_phrases)
|
|
150
149
|
end
|
|
151
150
|
end
|
|
152
151
|
|
|
@@ -156,7 +155,7 @@ class StoryKey::Console::Recover < StoryKey::Base
|
|
|
156
155
|
input = gets
|
|
157
156
|
input = default if input.blank?
|
|
158
157
|
@num_tail_entries = input.to_i.tap do |i|
|
|
159
|
-
quit(
|
|
158
|
+
quit("Invalid number") unless i.in?(1..max_parts_in_phrase)
|
|
160
159
|
end
|
|
161
160
|
end
|
|
162
161
|
|
|
@@ -176,7 +175,7 @@ class StoryKey::Console::Recover < StoryKey::Base
|
|
|
176
175
|
end
|
|
177
176
|
|
|
178
177
|
def board_rows # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
|
179
|
-
[version_lead].tap do |ary|
|
|
178
|
+
[ version_lead ].tap do |ary|
|
|
180
179
|
idx = 0
|
|
181
180
|
entry_slices.map do |entry_group, row|
|
|
182
181
|
parts = []
|
|
@@ -187,8 +186,8 @@ class StoryKey::Console::Recover < StoryKey::Base
|
|
|
187
186
|
idx += 1
|
|
188
187
|
end
|
|
189
188
|
|
|
190
|
-
str = parts.join(
|
|
191
|
-
str += (last_row ?
|
|
189
|
+
str = parts.join(" ")
|
|
190
|
+
str += (last_row ? "." : ",")
|
|
192
191
|
ary << str
|
|
193
192
|
end
|
|
194
193
|
end
|
|
@@ -209,7 +208,7 @@ class StoryKey::Console::Recover < StoryKey::Base
|
|
|
209
208
|
end
|
|
210
209
|
|
|
211
210
|
def move_entry_cursor(key)
|
|
212
|
-
@entry_idx = entry_idx.send((key == :left ?
|
|
211
|
+
@entry_idx = entry_idx.send((key == :left ? "-" : "+"), 1) % entries.size
|
|
213
212
|
clear_user_str
|
|
214
213
|
clear_options
|
|
215
214
|
end
|
|
@@ -217,7 +216,7 @@ class StoryKey::Console::Recover < StoryKey::Base
|
|
|
217
216
|
def move_option_cursor(key)
|
|
218
217
|
@option_idx =
|
|
219
218
|
if options.any?
|
|
220
|
-
option_idx.send((key == :up ?
|
|
219
|
+
option_idx.send((key == :up ? "-" : "+"), 1) % options.size
|
|
221
220
|
else
|
|
222
221
|
0
|
|
223
222
|
end
|
|
@@ -250,16 +249,16 @@ class StoryKey::Console::Recover < StoryKey::Base
|
|
|
250
249
|
end
|
|
251
250
|
|
|
252
251
|
def decolorize(text)
|
|
253
|
-
text.gsub(/\e\[\d+m/,
|
|
252
|
+
text.gsub(/\e\[\d+m/, "")
|
|
254
253
|
end
|
|
255
254
|
|
|
256
255
|
def draw
|
|
257
|
-
viewport.draw(user_prompt, Size([0, 0]), board_view, options_view)
|
|
256
|
+
viewport.draw(user_prompt, Size([ 0, 0 ]), board_view, options_view)
|
|
258
257
|
end
|
|
259
258
|
|
|
260
259
|
def user_prompt
|
|
261
260
|
hr = FRAME_HORIZONTAL * 36
|
|
262
|
-
Partial.new([hr, instructions, hr, "#{prompt}#{user_str}"])
|
|
261
|
+
Partial.new([ hr, instructions, hr, "#{prompt}#{user_str}" ])
|
|
263
262
|
end
|
|
264
263
|
|
|
265
264
|
def board_view
|
|
@@ -291,7 +290,7 @@ class StoryKey::Console::Recover < StoryKey::Base
|
|
|
291
290
|
end
|
|
292
291
|
|
|
293
292
|
def parts_of_speech
|
|
294
|
-
@parts_of_speech ||= entries.map { |w| w.tr(
|
|
293
|
+
@parts_of_speech ||= entries.map { |w| w.tr("[]", "") }
|
|
295
294
|
end
|
|
296
295
|
|
|
297
296
|
def lex
|
data/lib/story_key/console.rb
CHANGED
|
@@ -1,71 +1,73 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
1
|
class StoryKey::Console < Thor
|
|
3
|
-
package_name
|
|
2
|
+
package_name "StoryKey"
|
|
4
3
|
|
|
5
|
-
desc
|
|
4
|
+
desc "new [BITSIZE]",
|
|
6
5
|
<<~TEXT
|
|
7
6
|
Create a new key/story (default #{StoryKey::DEFAULT_BITSIZE} bits, max #{StoryKey::MAX_BITSIZE})
|
|
8
7
|
TEXT
|
|
9
8
|
option :image,
|
|
10
|
-
desc:
|
|
9
|
+
desc: "Whether to generate an image (requires OpenAI key and ImageMagick)",
|
|
11
10
|
type: :boolean,
|
|
12
|
-
aliases:
|
|
11
|
+
aliases: "-i"
|
|
12
|
+
|
|
13
13
|
def new(bitsize = StoryKey::DEFAULT_BITSIZE)
|
|
14
14
|
key, story = StoryKey.generate(bitsize: bitsize.to_i)
|
|
15
15
|
puts story_str(key, story)
|
|
16
16
|
print_image_path(story.tokenized, story.phrases) if options[:image]
|
|
17
17
|
rescue StoryKey::KeyTooLarge
|
|
18
|
-
quit
|
|
18
|
+
quit "Key too large"
|
|
19
19
|
end
|
|
20
20
|
|
|
21
|
-
desc
|
|
22
|
-
|
|
21
|
+
desc "encode [KEY]",
|
|
22
|
+
"Encode a key passed as an argument or from a file"
|
|
23
23
|
option :file,
|
|
24
|
-
desc:
|
|
25
|
-
aliases:
|
|
24
|
+
desc: "File containing key",
|
|
25
|
+
aliases: "-f"
|
|
26
26
|
option :format,
|
|
27
|
-
desc:
|
|
27
|
+
desc: "Format of key",
|
|
28
28
|
enum: %w[base58 hex bin dec],
|
|
29
|
-
default:
|
|
29
|
+
default: "base58"
|
|
30
30
|
option :image,
|
|
31
|
-
desc:
|
|
31
|
+
desc: "Whether to generate an image (requires OpenAI key and ImageMagick)",
|
|
32
32
|
type: :boolean,
|
|
33
|
-
aliases:
|
|
33
|
+
aliases: "-i"
|
|
34
|
+
|
|
34
35
|
def encode(key = nil)
|
|
35
36
|
key ||= File.read(options[:file])
|
|
36
37
|
story = StoryKey.encode(key:, format: options[:format])
|
|
37
38
|
puts story_str(key, story)
|
|
38
39
|
print_image_path(story.tokenized, story.phrases) if options[:image]
|
|
39
40
|
rescue StoryKey::InvalidFormat
|
|
40
|
-
quit
|
|
41
|
+
quit "Invalid format"
|
|
41
42
|
rescue StoryKey::KeyTooLarge
|
|
42
|
-
quit
|
|
43
|
+
quit "Key too large"
|
|
43
44
|
rescue Errno::ENOENT
|
|
44
|
-
quit
|
|
45
|
+
quit "Invalid file specified"
|
|
45
46
|
end
|
|
46
47
|
|
|
47
|
-
desc
|
|
48
|
-
|
|
48
|
+
desc "decode [STORY]",
|
|
49
|
+
"Decode a story passed as an argument or from a file"
|
|
49
50
|
option :file,
|
|
50
|
-
desc:
|
|
51
|
-
aliases:
|
|
51
|
+
desc: "File containing story",
|
|
52
|
+
aliases: "-f"
|
|
52
53
|
option :format,
|
|
53
|
-
desc:
|
|
54
|
+
desc: "Format of key",
|
|
54
55
|
enum: %w[base58 hex bin dec],
|
|
55
|
-
default:
|
|
56
|
+
default: "base58"
|
|
57
|
+
|
|
56
58
|
def decode(story = nil)
|
|
57
59
|
story ||= File.read(options[:file])
|
|
58
60
|
format ||= options[:format]
|
|
59
61
|
puts StoryKey.decode(story:, format:)
|
|
60
62
|
rescue StoryKey::InvalidVersion
|
|
61
|
-
puts
|
|
63
|
+
puts "Invalid version"
|
|
62
64
|
exit
|
|
63
65
|
rescue StoryKey::InvalidChecksum, StoryKey::InvalidWord
|
|
64
|
-
puts
|
|
66
|
+
puts "Invalid story"
|
|
65
67
|
exit
|
|
66
68
|
end
|
|
67
69
|
|
|
68
|
-
desc
|
|
70
|
+
desc "recover", "Decode a story interactively"
|
|
69
71
|
def recover
|
|
70
72
|
StoryKey.recover
|
|
71
73
|
end
|
|
@@ -73,9 +75,9 @@ class StoryKey::Console < Thor
|
|
|
73
75
|
private
|
|
74
76
|
|
|
75
77
|
def print_image_path(seed, phrases)
|
|
76
|
-
puts
|
|
78
|
+
puts "Generating image..."
|
|
77
79
|
image_path = StoryKey::ImageGenerator.call(seed:, phrases:)
|
|
78
|
-
puts
|
|
80
|
+
puts "No panels generated - check your OpenAI key" if image_path.empty?
|
|
79
81
|
puts "#{titleize('Image')} #{image_path}"
|
|
80
82
|
end
|
|
81
83
|
|
|
@@ -90,11 +92,11 @@ class StoryKey::Console < Thor
|
|
|
90
92
|
|
|
91
93
|
def story_str(key, story)
|
|
92
94
|
[
|
|
93
|
-
titleize(
|
|
95
|
+
titleize("Key"),
|
|
94
96
|
key,
|
|
95
|
-
titleize(
|
|
97
|
+
titleize("Story"),
|
|
96
98
|
story.humanized,
|
|
97
|
-
titleize(
|
|
99
|
+
titleize("Seed Phrase"),
|
|
98
100
|
story.tokenized
|
|
99
101
|
].join("\n")
|
|
100
102
|
end
|
data/lib/story_key/data.rb
CHANGED