cw 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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