cw 0.0.1

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.
Files changed (60) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/Gemfile +11 -0
  4. data/LICENSE +21 -0
  5. data/README.md +21 -0
  6. data/Rakefile +1 -0
  7. data/audio/audio_output.wav +0 -0
  8. data/audio/audio_output.wav0000.mp3 +0 -0
  9. data/audio/dash.wav +0 -0
  10. data/audio/dot.wav +0 -0
  11. data/audio/e_space.wav +0 -0
  12. data/audio/space.wav +0 -0
  13. data/cw.gemspec +18 -0
  14. data/daily.rb +182 -0
  15. data/data/text/abbreviations.txt +1 -0
  16. data/data/text/common_words.txt +90 -0
  17. data/data/text/cw_conversation.txt +1 -0
  18. data/data/text/most_common_words.txt +1 -0
  19. data/data/text/progress.txt +1 -0
  20. data/data/text/q_codes.txt +1 -0
  21. data/data/text/tom_sawyer.txt +6477 -0
  22. data/example.rb +139 -0
  23. data/lib/cw.rb +111 -0
  24. data/lib/cw/alphabet.rb +29 -0
  25. data/lib/cw/audio_player.rb +63 -0
  26. data/lib/cw/book.rb +239 -0
  27. data/lib/cw/book_details.rb +47 -0
  28. data/lib/cw/cl.rb +112 -0
  29. data/lib/cw/cw_dsl.rb +211 -0
  30. data/lib/cw/cw_encoding.rb +56 -0
  31. data/lib/cw/cw_params.rb +29 -0
  32. data/lib/cw/cw_threads.rb +36 -0
  33. data/lib/cw/file_details.rb +13 -0
  34. data/lib/cw/key_input.rb +53 -0
  35. data/lib/cw/monitor.rb +36 -0
  36. data/lib/cw/monitor_keys.rb +37 -0
  37. data/lib/cw/numbers.rb +29 -0
  38. data/lib/cw/print.rb +137 -0
  39. data/lib/cw/process.rb +11 -0
  40. data/lib/cw/progress.rb +27 -0
  41. data/lib/cw/randomize.rb +73 -0
  42. data/lib/cw/repeat_word.rb +91 -0
  43. data/lib/cw/rss.rb +71 -0
  44. data/lib/cw/sentence.rb +78 -0
  45. data/lib/cw/speak.rb +11 -0
  46. data/lib/cw/spoken.rb +11 -0
  47. data/lib/cw/str.rb +67 -0
  48. data/lib/cw/stream.rb +161 -0
  49. data/lib/cw/test_letters.rb +52 -0
  50. data/lib/cw/test_words.rb +59 -0
  51. data/lib/cw/tester.rb +221 -0
  52. data/lib/cw/timing.rb +92 -0
  53. data/lib/cw/tone_generator.rb +225 -0
  54. data/lib/cw/voice.rb +16 -0
  55. data/lib/cw/words.rb +182 -0
  56. data/read_book.rb +33 -0
  57. data/test/run_tests_continuously.rb +4 -0
  58. data/test/test_cw.rb +527 -0
  59. data/test/test_stream.rb +401 -0
  60. metadata +102 -0
data/example.rb ADDED
@@ -0,0 +1,139 @@
1
+ require_relative 'lib/cw'
2
+
3
+ CW.new do
4
+ comment 'read book feed (1 sentence)'
5
+ play_book(sentences: 1)
6
+ end
7
+
8
+ CW.new do
9
+ comment 'read book feed (1 minute)'
10
+ play_book(duration: 1)
11
+ end
12
+
13
+ CW.new do
14
+ comment 'read rss feed (1 article)'
15
+ read_rss(:reuters, 1)
16
+ end
17
+
18
+ CW.new do
19
+ name 'test straight alphabet'
20
+ alphabet
21
+ end
22
+
23
+ CW.new do
24
+ comment 'test straight numbers'
25
+ numbers
26
+ end
27
+
28
+ CW.new do
29
+ wpm 18
30
+ ewpm 12
31
+ load_abbreviations
32
+ shuffle
33
+ end
34
+
35
+ CW.new do
36
+ wpm 18
37
+ ewpm 12
38
+ load_q_codes
39
+ shuffle
40
+ end
41
+
42
+ def cw_settings
43
+ shuffle
44
+ wpm 20
45
+ ewpm 15
46
+ # use_ebook2cw
47
+ use_ruby_tone
48
+ mark_words
49
+ word_count 5
50
+ word_size 4
51
+ print_letters
52
+ puts self.to_s
53
+ end
54
+
55
+ CW.new do
56
+ comment 'test random letters'
57
+ random_letters(size: 4)
58
+ cw_settings
59
+ end
60
+
61
+ CW.new do
62
+ comment 'test random numbers'
63
+ # use_ebook2cw
64
+ cw_settings
65
+ random_numbers(count: 2, size: 5)
66
+ end
67
+
68
+ CW.new do
69
+ comment 'test random letters numbers'
70
+ # use_ebook2cw
71
+ cw_settings
72
+ random_letters_numbers(count: 2, size: 11)
73
+ end
74
+
75
+ wpm = 15
76
+ ewpm = 12
77
+ loop do
78
+
79
+ test = CW.new
80
+ # test.use_ebook2cw
81
+ test.comment 'test words beginning with b'
82
+ test.shuffle
83
+ test.wpm wpm
84
+ test.effective_wpm ewpm
85
+ test.beginning_with 'b'
86
+ test.word_size 4
87
+ test.word_count 4
88
+ puts test.to_s
89
+ test.test_words
90
+ test = nil
91
+
92
+ test = CW.new
93
+ test.comment 'test words including ing'
94
+ # test.use_ebook2cw
95
+ test.shuffle
96
+ test.wpm wpm
97
+ test.effective_wpm ewpm
98
+ test.including 'ing'
99
+ test.word_count 5
100
+ test.test_words
101
+ test = nil
102
+
103
+ # test = CW.new
104
+ # test.comment 'test ing'
105
+ # test.use_ebook2cw
106
+ ## test.shuffle
107
+ # test.wpm wpm
108
+ # test.effective_wpm ewpm
109
+ # test.beginning_with ['f']
110
+ # test.word_size 4
111
+ # test.word_count 5
112
+ # test.test_words
113
+ #
114
+ # test = CW.new
115
+ # test.comment 'test ing'
116
+ # test.use_ruby_tone
117
+ ## test.shuffle
118
+ # test.wpm wpm
119
+ # test.effective_wpm ewpm
120
+ # test.beginning_with ['f']
121
+ # test.word_size 4
122
+ # test.word_count 5
123
+ # test.test_words
124
+
125
+ # test = CW.new
126
+ # test.comment 'test ing'
127
+ # test.shuffle
128
+ # test.wpm wpm
129
+ # test.effective_wpm ewpm
130
+ # test.beginning_with ['j']
131
+ # test.word_size 4
132
+ # test.word_count 5
133
+ # test.test_words
134
+ #
135
+ wpm += 2
136
+ break if wpm >= 24
137
+ end
138
+
139
+ puts 'done'
data/lib/cw.rb ADDED
@@ -0,0 +1,111 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative 'cw/version'
4
+ require_relative 'cw/file_details'
5
+ require_relative 'cw/process'
6
+ require_relative 'cw/cw_dsl'
7
+ require_relative 'cw/randomize'
8
+ require_relative 'cw/sentence'
9
+ require_relative 'cw/alphabet'
10
+ require_relative 'cw/numbers'
11
+ require_relative 'cw/str'
12
+ require_relative 'cw/rss'
13
+ require_relative 'cw/words'
14
+ require_relative 'cw/cl'
15
+ require_relative 'cw/cw_params'
16
+ require_relative 'cw/key_input'
17
+ require_relative 'cw/stream'
18
+ require_relative 'cw/timing'
19
+ require_relative 'cw/print'
20
+ require_relative 'cw/audio_player'
21
+ require_relative 'cw/cw_threads'
22
+ require_relative 'cw/book_details'
23
+ require_relative 'cw/tester'
24
+ require_relative 'cw/test_words'
25
+ require_relative 'cw/test_letters'
26
+ require_relative 'cw/repeat_word'
27
+ require_relative 'cw/book'
28
+ require_relative 'cw/cw_encoding'
29
+ require_relative 'cw/tone_generator.rb'
30
+ require_relative 'cw/progress'
31
+
32
+ # class CW provides Morse code generation functionality
33
+
34
+ class CW < CwDsl
35
+
36
+ attr_accessor :dry_run
37
+ attr_accessor :quit
38
+
39
+ def test_letters
40
+ @inhibit_block_run = true
41
+ test_letters = TestLetters.new
42
+ test_letters.run @words
43
+ end
44
+
45
+ def repeat_word
46
+ @inhibit_block_run = true
47
+ repeat_word = RepeatWord.new
48
+ repeat_word.run @words
49
+ end
50
+
51
+ def initialize(&block)
52
+
53
+ super
54
+
55
+ load_common_words# unless @words.exist?
56
+ instance_eval(&block) if block
57
+ run unless Params.pause if (block && ! @inhibit_block_run)
58
+ end
59
+
60
+ def to_s
61
+ @str.to_s
62
+ end
63
+
64
+ def run_word_test
65
+ test_words = TestWords.new
66
+ test_words.run @words
67
+ end
68
+
69
+ def test_words
70
+ run_word_test
71
+ end
72
+
73
+ def play_book args = {}
74
+ @inhibit_block_run = true
75
+ details = BookDetails.new
76
+ details.arguments(args)
77
+ book = Book.new details
78
+ book.run @words
79
+ end
80
+
81
+ def read_rss(source, show_count = 3)
82
+ @inhibit_block_run = true
83
+ rss, = Rss.new
84
+ rss.read_rss(source, show_count)
85
+ loop do
86
+ article = rss.next_article
87
+ return unless article
88
+ test_words = TestWords.new
89
+ @words.assign article
90
+ test_words.run @words
91
+ end
92
+ end
93
+
94
+ def run ; test_words ; end
95
+
96
+ alias_method :ewpm, :effective_wpm
97
+ alias_method :no_run, :pause
98
+ alias_method :comment, :name
99
+ # alias_method :repeat_word, :double_words
100
+ alias_method :word_length, :word_size
101
+ alias_method :word_shuffle, :shuffle
102
+ alias_method :having_size_of, :word_size
103
+ alias_method :number_of_words, :word_count
104
+ alias_method :words_including, :including
105
+ alias_method :words_ending_with, :ending_with
106
+ alias_method :random_alphanumeric, :random_letters_numbers
107
+ alias_method :words_beginning_with, :beginning_with
108
+ alias_method :words_no_longer_than, :no_longer_than
109
+ alias_method :words_no_shorter_than, :no_shorter_than
110
+
111
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+
3
+ #class Alphabet provides alphabet generation functionality
4
+
5
+ class Alphabet
6
+
7
+ def initialize(options = {})
8
+ @options = options
9
+ end
10
+
11
+ def alphabet
12
+ 'abcdefghijklmnopqrstuvwxyz'
13
+ end
14
+
15
+ def reverse_alphabet_maybe
16
+ @letters.reverse! if @options[:reverse]
17
+ end
18
+
19
+ def shuffle_alphabet_maybe
20
+ @letters = @letters.split('').shuffle.join if @options[:shuffle]
21
+ end
22
+
23
+ def generate
24
+ @letters = alphabet
25
+ shuffle_alphabet_maybe
26
+ reverse_alphabet_maybe
27
+ @letters.split('').join(' ')
28
+ end
29
+ end
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+
3
+ class AudioPlayer
4
+
5
+ def tone
6
+ @tone ||= ToneGenerator.new
7
+ end
8
+
9
+ def play_command
10
+ @play_command ||= 'afplay'
11
+ end
12
+
13
+ def play_filename_for_ebook2cw
14
+ @play_filename ||= "#{Params.audio_dir}/#{Params.audio_filename}0000.mp3"
15
+ end
16
+
17
+ def convert_words_with_ebook2cw words
18
+ words = words.gsub("\n","")
19
+ cl = Cl.new.cl_echo(words)
20
+ ! @dry_run ? `#{cl}` : cl
21
+ end
22
+
23
+ def convert_words words
24
+ tone.generate words unless Params.use_ebook2cw
25
+ convert_words_with_ebook2cw words if Params.use_ebook2cw
26
+ end
27
+
28
+ def play_filename
29
+ return play_filename_for_ebook2cw if Params.use_ebook2cw
30
+ tone.play_filename
31
+ end
32
+
33
+ def play
34
+ cmd = play_command + ' ' + play_filename
35
+ @pid = ! @dry_run ? Process.spawn(cmd) : cmd
36
+ end
37
+
38
+ def stop
39
+ begin
40
+ Process.kill(:TERM, @pid)
41
+ Process.wait(@pid)
42
+ rescue
43
+ end
44
+ end
45
+
46
+ def play_tone tone
47
+ `#{play_command + ' ' + tone}`
48
+ end
49
+
50
+ def play_cmd_for_ps
51
+ '[' << play_command[0] << ']' << play_command[1..-1]
52
+ end
53
+
54
+ def still_playing?
55
+ ps = `ps -ewwo pid,args | grep #{play_cmd_for_ps}`
56
+ return ps.include? "#{play_filename_for_ebook2cw}" if Params.use_ebook2cw
57
+ return ps.include? tone.play_filename unless Params.use_ebook2cw
58
+ end
59
+
60
+ def startup_delay
61
+ 0.2
62
+ end
63
+ end
data/lib/cw/book.rb ADDED
@@ -0,0 +1,239 @@
1
+ # encoding: utf-8
2
+
3
+ class Book < FileDetails
4
+
5
+ include Tester
6
+
7
+ def initialize book_details
8
+ # prn.print_advice('Test Words')
9
+ @book_details = book_details
10
+ @print_letters = Params.print_letters
11
+ super()
12
+ read_book book_location
13
+ find_sentences
14
+
15
+ # print_book_advice
16
+ end
17
+
18
+ def sentence ; @sentence ||= Sentence.new ; end
19
+ def find_sentences ; sentence.find_all ; end
20
+ def raw_text ; sentence.text ; end
21
+ def read_book(book) ; sentence.read_book(book) ; end
22
+ def next_sentence ; sentence.next ; end
23
+ def change_sentence ; sentence.change ; end
24
+ def change_sentence? ; sentence.change? ; end
25
+ def repeat_sentence? ; sentence.repeat? ; end
26
+ def current_sentence ; sentence.current ; end
27
+ def current_sentence_ary ; sentence.current_to_array ; end
28
+ def sentence_index ; sentence.index ; end
29
+ def play_repeat_tone ; audio_play_tone @repeat_tone ; end
30
+ def audio_play_tone t ; audio.play_tone(t) ; end
31
+ def play_r_tone ; audio_play_tone @r_tone ; end
32
+ def complete_word? ; get_word_last_char == space ; end
33
+ def audio_stop ; audio.stop if audio_still_playing?; end
34
+ def book_location ; @book_details.book_location ; end
35
+ def print_letters? ; @print_letters && ! quit? ; end
36
+ def reset_sentence_flags ; sentence.reset_flags ; end
37
+ def audio_play_sentence ; audio.play ; end
38
+ def print_book_advice ; print.print_advice('Play Book') ; end
39
+
40
+ def change_or_repeat_sentence?
41
+ sentence.change_or_repeat?
42
+ end
43
+
44
+ def change_repeat_or_quit?
45
+ change_or_repeat_sentence? || quit?
46
+ end
47
+
48
+ def check_sentence_navigation chr
49
+ sentence.check_sentence_navigation chr
50
+ end
51
+
52
+ def progress_file
53
+ File.expand_path(@progress_file, @text_folder)
54
+ end
55
+
56
+ def get_book_progress
57
+ sentence.read_progress progress_file
58
+ @current_sentence_index = sentence_index
59
+ end
60
+
61
+ def write_book_progress
62
+ sentence.write_progress progress_file
63
+ end
64
+
65
+ def audio_play_repeat_tone_maybe
66
+ play_repeat_tone if repeat_sentence?
67
+ end
68
+
69
+ def monitor_keys
70
+ loop do
71
+ get_key_input
72
+ check_quit_key_input
73
+ break if quit?
74
+ check_sentence_navigation key_chr
75
+ build_word_maybe
76
+ end
77
+ end
78
+
79
+ def process_input_word_maybe
80
+ if @word_to_process
81
+ if @book_details.args[:output] == :letter
82
+ stream.match_first_active_element @process_input_word # .strip #todo
83
+ else
84
+ stream.match_last_active_element @process_input_word.strip #todo
85
+ end
86
+ @process_input_word = @word_to_process = nil
87
+ end
88
+ end
89
+
90
+ def build_word_maybe
91
+ @input_word ||= empty_string
92
+ @input_word << key_chr if is_relevant_char?
93
+ if @book_details.args[:output] == :letter
94
+ move_word_to_process if is_relevant_char? #todo
95
+ else
96
+ move_word_to_process if complete_word?
97
+ end
98
+ end
99
+
100
+ def add_space sentence
101
+ sentence + space
102
+ end
103
+
104
+ def compile_sentence
105
+ audio.convert_words add_space current_sentence
106
+ end
107
+
108
+ def compile_and_play
109
+ compile_sentence
110
+ audio_play_sentence
111
+ start_sync
112
+ end
113
+
114
+ def change_and_kill_audio
115
+ change_sentence
116
+ audio_stop
117
+ end
118
+
119
+ def next_sentence_or_quit?
120
+ playing = audio_still_playing?
121
+ next_sentence unless playing
122
+ sleep 0.01 if playing
123
+ if change_repeat_or_quit?
124
+ change_and_kill_audio
125
+ #todo prn.newline unless quit?
126
+ true
127
+ end
128
+ end
129
+
130
+ def await_next_sentence_or_quit
131
+ loop do
132
+ break if next_sentence_or_quit?
133
+ end
134
+ end
135
+
136
+ def quit_or_process_input?
137
+ quit? || @word_to_process
138
+ end
139
+
140
+ def process_letter letr
141
+ current_word.process_letter letr
142
+ sleep_char_delay letr
143
+ end
144
+
145
+ def print_marked_maybe
146
+ @popped = stream.pop_next_marked
147
+ if @book_details.args[:output] == :letter
148
+ print.char_result(@popped) if(@popped && ! print_letters?) #todo
149
+ else
150
+ print.results(@popped) if(@popped && ! print_letters?)
151
+ end
152
+ end
153
+
154
+ def print_words words
155
+ timing.init_char_timer
156
+ (words + space).each_char do |letr|
157
+ process_letter letr
158
+ stream.add_char(letr) if @book_details.args[:output] == :letter
159
+ loop do
160
+ process_space_maybe(letr) unless @book_details.args[:output] == :letter
161
+ process_word_maybe
162
+ if change_repeat_or_quit?
163
+ break
164
+ end
165
+ break if timing.char_delay_timeout?
166
+ end
167
+ print.prn letr if print_letters?
168
+ break if change_repeat_or_quit?
169
+ end
170
+ end
171
+
172
+ def print_words_for_current_sentence
173
+ # puts current_sentence
174
+ print_words current_sentence
175
+ end
176
+
177
+ def make_sentence_index_current
178
+ @current_sentence_index = sentence_index
179
+ end
180
+
181
+ def sentence_index_current?
182
+ @current_sentence_index && (@current_sentence_index == sentence_index)
183
+ end
184
+
185
+ def play_sentences_until_quit
186
+ get_book_progress
187
+ loop do
188
+ check_sentence_count :play
189
+ sync_with_print
190
+ audio_play_repeat_tone_maybe
191
+ reset_sentence_flags
192
+ compile_and_play
193
+ await_next_sentence_or_quit
194
+ break if quit?
195
+ end
196
+ print_words_exit unless @print_letters
197
+ end
198
+
199
+ def check_sentence_count source
200
+ if @book_details.session_finished? source
201
+ audio_stop
202
+ quit
203
+ reset_stdin
204
+ kill_threads
205
+ end
206
+ end
207
+
208
+ def print_sentences_until_quit
209
+ loop do
210
+ check_sentence_count :print
211
+ sync_with_play
212
+ break if quit?
213
+ sync_with_audio_player
214
+ print_words_for_current_sentence
215
+ print.reset
216
+ puts
217
+ end
218
+ end
219
+
220
+ def play_sentences_thread
221
+ play_sentences_until_quit
222
+ write_book_progress
223
+ # kill_threads
224
+ print "\n\rplay has quit " if @debug
225
+ end
226
+
227
+ def print_sentences_thread
228
+ print_sentences_until_quit
229
+ kill_threads
230
+ print "\n\rprint has quit " if @debug
231
+ end
232
+
233
+ def thread_processes
234
+ [:monitor_keys_thread,
235
+ :play_sentences_thread,
236
+ :print_sentences_thread]
237
+ end
238
+
239
+ end