cw 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/example.rb CHANGED
@@ -198,6 +198,24 @@ cw do
198
198
  word_count 4
199
199
  end
200
200
 
201
+ cw do
202
+ comment "test 5 callsigns"
203
+ wpm 20
204
+ callsign * 5
205
+ end
206
+
207
+ puts "cq de callsign k 5 times"
208
+ 5.times do
209
+ cw do
210
+ comment 'random frequency, random wpm callsign with pre and postamble'
211
+ frequency 500 + rand(400)
212
+ wpm 25 + rand(10)
213
+ callsign
214
+ (words.unshift "cqde") << 'k'
215
+ print_letters
216
+ end
217
+ end
218
+
201
219
  # See documentation for more details - and more commands.
202
220
 
203
221
  puts 'done'
data/lib/cw.rb CHANGED
@@ -36,6 +36,9 @@ require_relative 'cw/book'
36
36
  require_relative 'cw/tone_generator'
37
37
  require_relative 'cw/progress'
38
38
  require_relative 'cw/common_words'
39
+ require_relative 'cw/callsign'
40
+
41
+ #require_relative 'cw/read.rb'
39
42
 
40
43
  def cw &block
41
44
  CW.new do
@@ -19,19 +19,29 @@ module CWG
19
19
  @options = options
20
20
  end
21
21
 
22
- # return string containing alphabet
22
+ # alphabet()
23
+ # Returns alphabet as string
24
+ # == Parameters:
25
+ # none
23
26
 
24
27
  def alphabet
25
28
  'abcdefghijklmnopqrstuvwxyz'
26
29
  end
27
30
 
28
- # reverse alphabet if :reverse option defined
31
+ # reverse_alphabet_maybe()
32
+ # reverse letters if reverse option set
33
+ # == Parameters:
34
+ # none
29
35
 
30
36
  def reverse_alphabet_maybe
31
37
  @letters.reverse! if @options[:reverse]
32
38
  end
33
39
 
40
+ # shuffle_alphabet_maybe()
34
41
  # shuffle alphabet if :shuffle option defined
42
+ # don't shuffle if in test environment
43
+ # == Parameters:
44
+ # none
35
45
 
36
46
  def shuffle_alphabet_maybe
37
47
  unless(ENV["CW_ENV"] == "test")
@@ -39,7 +49,10 @@ module CWG
39
49
  end
40
50
  end
41
51
 
42
- # include letters passed in as string if :include defined
52
+ # include_letters()
53
+ # include letters if :include option defined
54
+ # == Parameters:
55
+ # none
43
56
 
44
57
  def include_letters
45
58
  if @options[:include]
@@ -47,7 +60,10 @@ module CWG
47
60
  end
48
61
  end
49
62
 
50
- # exclude letters passed in as string if :exclude defined
63
+ # exclude_letters()
64
+ # exclude letters if :exclude option defined
65
+ # == Parameters:
66
+ # none
51
67
 
52
68
  def exclude_letters
53
69
  if @options[:exclude]
@@ -55,6 +71,7 @@ module CWG
55
71
  end
56
72
  end
57
73
 
74
+ # generate()
58
75
  # generate alphabet with options acted upon
59
76
  # == Returns:
60
77
  # alphabet or filtered alphabet
@@ -67,7 +84,5 @@ module CWG
67
84
  reverse_alphabet_maybe
68
85
  @letters.split('').join(' ')
69
86
  end
70
-
71
87
  end
72
-
73
88
  end
@@ -7,6 +7,7 @@ module CWG
7
7
 
8
8
  class AudioPlayer
9
9
 
10
+ include FileDetails
10
11
  include CWG::OStest
11
12
 
12
13
  def tone
@@ -33,11 +34,9 @@ module CWG
33
34
  end
34
35
 
35
36
  def play_filename_for_ebook2cw
36
- @play_filename ||= File.expand_path(Cfg.config["audio_filename"], audio_dir)
37
- end
38
-
39
- def audio_dir
40
- Cfg.config["audio_dir"]
37
+ @play_filename ||= File.join(audio_dir, audio_filename)
38
+ puts "@play_filename = #{@play_filename}"
39
+ @play_filename
41
40
  end
42
41
 
43
42
  def temp_filename_for_ebook2cw
@@ -55,7 +54,6 @@ module CWG
55
54
  File.rename(play_filename_for_ebook2cw + '0000.mp3', play_filename_for_ebook2cw)
56
55
  end
57
56
 
58
- #FIXME dry_run
59
57
  def convert_words_with_ebook2cw words
60
58
  words = words.delete("\n")
61
59
  cl = Cl.new.cl_echo(words)
@@ -64,7 +62,7 @@ module CWG
64
62
  end
65
63
 
66
64
  def convert_words words
67
- tone.generate words unless Cfg.config["use_ebook2cw"]
65
+ tone.generate words if Cfg.config["use_ebook2cw"].nil?
68
66
  convert_words_with_ebook2cw words if Cfg.config["use_ebook2cw"]
69
67
  end
70
68
 
@@ -73,7 +71,6 @@ module CWG
73
71
  tone.play_filename
74
72
  end
75
73
 
76
- #FIXME dry_run
77
74
  def play
78
75
  cmd = play_command + ' ' + play_filename
79
76
  @pid = ! @dry_run ? Process.spawn(cmd) : cmd
@@ -43,10 +43,6 @@ module CWG
43
43
  sentence.check_sentence_navigation chr
44
44
  end
45
45
 
46
- def progress_file
47
- File.expand_path(@progress_file, @text_folder)
48
- end
49
-
50
46
  def get_book_progress
51
47
  sentence.read_progress progress_file
52
48
  @current_sentence_index = sentence.index
@@ -8,21 +8,32 @@ module CWG
8
8
 
9
9
  include FileDetails
10
10
 
11
- def initialize
12
- book_directory
13
- book_name
14
- end
11
+ BOOK_NAME = "book.txt"
12
+ BOOK_DIR = TEXT
13
+ USER_BOOK_DEFAULT_DIR = "books"
15
14
 
16
15
  def book_name
17
- Cfg.config["book_name"]
16
+ @book_name ||=
17
+ Cfg.config["book_name"] ?
18
+ Cfg.config["book_name"] :
19
+ BOOK_NAME
20
+ end
21
+
22
+ def is_user_book_default_dir?
23
+ File.exists? USER_BOOK_DEFAULT_DIR
18
24
  end
19
25
 
20
- def book_directory
21
- File.join ROOT, Cfg.config["book_dir"]
26
+ def book_dir
27
+ @book_dir ||=
28
+ Cfg.config["book_dir"] ?
29
+ File.join(WORK_DIR, Cfg.config["book_dir"]) :
30
+ is_user_book_default_dir? ?
31
+ USER_BOOK_DEFAULT_DIR :
32
+ BOOK_DIR
22
33
  end
23
34
 
24
35
  def book_location
25
- File.expand_path(book_name, book_directory)
36
+ File.expand_path(book_name, book_dir)
26
37
  end
27
38
 
28
39
  def arguments args
@@ -0,0 +1,59 @@
1
+ module CWG
2
+
3
+ class Callsign
4
+
5
+ include FileDetails
6
+
7
+ def callsigns
8
+ if @callsigns.nil?
9
+ @callsigns = load_callsigns
10
+ end
11
+ @callsigns
12
+ end
13
+
14
+ def load_callsigns
15
+ File.open(CALLS_FILENAME, "r") do |calls|
16
+ YAML::load(calls)
17
+ end
18
+ end
19
+
20
+
21
+ def rand_val
22
+ rand(100)
23
+ end
24
+
25
+ def select_part country = :uk, partial
26
+ pc = rand_val
27
+ weight = callsigns[country][partial][:weight]
28
+ tot_wt = 0
29
+ weight.each_with_index do |wt, idx|
30
+ tot_wt += wt
31
+ if pc < tot_wt
32
+ part = callsigns[country][partial][:option][idx]
33
+ return part unless(part.class == Range)
34
+ return part.to_a.sample
35
+ end
36
+ end
37
+ end
38
+
39
+ def partial_name count
40
+ "partial_#{count}".to_sym
41
+ end
42
+
43
+ def construct
44
+ call = ''
45
+ 0.upto(4) do |count|
46
+ call << select_part(partial_name(count))
47
+ end
48
+ call.strip
49
+ end
50
+
51
+ def * number
52
+ calls = []
53
+ number.times do
54
+ calls << construct
55
+ end
56
+ calls
57
+ end
58
+ end
59
+ end
@@ -6,6 +6,8 @@ module CWG
6
6
 
7
7
  class Cl
8
8
 
9
+ include FileDetails
10
+
9
11
  def initialize
10
12
  @tone = {
11
13
  sinewave: 0,
@@ -34,22 +36,21 @@ module CWG
34
36
  freq ? "-f #{freq} " : ''
35
37
  end
36
38
 
39
+ def wave type
40
+ return '' unless(Cfg.config["tone"].to_s == type)
41
+ "-T #{@tone[type.to_sym]} "
42
+ end
43
+
37
44
  def cl_squarewave
38
- "Cfg.config[\"tone\"] = #{Cfg.config["tone"]}"
39
- return '' unless Cfg.config["tone"].to_s == "squarewave"
40
- "-T #{@tone[:squarewave]} "
45
+ wave 'squarewave'
41
46
  end
42
47
 
43
48
  def cl_sawtooth
44
- "Cfg.config[\"tone\"] = #{Cfg.config["tone"]}"
45
- return '' unless Cfg.config["tone"].to_s == "sawtooth"
46
- "-T #{@tone[:sawtooth]} "
49
+ wave "sawtooth"
47
50
  end
48
51
 
49
52
  def cl_sinewave
50
- "Cfg.config[\"tone\"] = #{Cfg.config["tone"]}"
51
- return '' unless Cfg.config["tone"].to_s == "sinewave"
52
- "-T #{@tone[:sinewave]} "
53
+ wave "sinewave"
53
54
  end
54
55
 
55
56
  def cl_author
@@ -64,11 +65,11 @@ module CWG
64
65
 
65
66
  def cl_noise
66
67
  Cfg.config["noise"] ?
67
- "-N 5 -B 1000 " : ''
68
+ "-N 10 -B 800 " : ''
68
69
  end
69
70
 
70
71
  def cl_audio_filename
71
- "-o \"#{File.expand_path(Cfg.config["audio_filename"], Cfg.config["audio_dir"])}\" "
72
+ "-o \"#{File.join(audio_dir, audio_filename)}\" "
72
73
  end
73
74
 
74
75
  def coarse_quality(quality)
@@ -8,8 +8,31 @@ module CWG
8
8
  @words = []
9
9
  end
10
10
 
11
+ def custom_dict_dir
12
+ File.join(WORK_DIR, Cfg.config["dictionary_dir"])
13
+ end
14
+
15
+ def dictionary_dir
16
+ @dictionary_dir ||=
17
+ Cfg.config["dictionary_dir"] ?
18
+ custom_dict_dir :
19
+ DICT_DIR
20
+ end
21
+
22
+ def dict_filename
23
+ @dict_filename ||=
24
+ Cfg.config["dictionary_name"] ?
25
+ Cfg.config["dictionary_name"] :
26
+ DICT_FILENAME
27
+ end
28
+
29
+ def dictionary
30
+ @dictionary ||=
31
+ File.join(dictionary_dir, dict_filename)
32
+ end
33
+
11
34
  def all
12
- File.foreach(ENGLISH_DICT).collect do |line|
35
+ File.foreach(dictionary).collect do |line|
13
36
  line.chomp
14
37
  end
15
38
  end
@@ -17,7 +40,7 @@ module CWG
17
40
  def low last
18
41
  results = []
19
42
  count = 0
20
- File.foreach(ENGLISH_DICT).collect do |line|
43
+ File.foreach(dictionary).collect do |line|
21
44
  if count <= last
22
45
  results << line.chomp
23
46
  end
@@ -30,7 +53,7 @@ module CWG
30
53
  def mid first, last
31
54
  results = []
32
55
  count = 0
33
- File.foreach(ENGLISH_DICT).collect do |line|
56
+ File.foreach(dictionary).collect do |line|
34
57
  if (count >= first) && (count <= last)
35
58
  results << line.chomp
36
59
  end
@@ -18,18 +18,29 @@ module CWG
18
18
 
19
19
  def self.config
20
20
  unless @config
21
- @config = ParseConfig.new(CONFIG_FILENAME)
21
+ @config = ParseConfig.new(CONFIG_PATH)
22
22
  CONFIG_METHODS.each do |method|
23
23
  unless @config[method.to_s]
24
24
  @config.add method.to_s, nil
25
25
  end
26
26
  end
27
+ self.user_config
28
+ @config.params["wpm"] = 50 if(ENV["CW_ENV"] == "test")
29
+ @config.params["effective_wpm"] = 50 if(ENV["CW_ENV"] == "test")
30
+ # puts " @config[wpm] = #{@config['wpm']}"
27
31
  end
28
- @config.params["wpm"] = 50 if(ENV["CW_ENV"] == "test")
29
- @config.params["effective_wpm"] = 50 if(ENV["CW_ENV"] == "test")
32
+ # puts "@config = #{@config.params}"
30
33
  @config
31
34
  end
32
35
 
36
+ def self.user_config
37
+ user_cfg = File.join(WORK_DIR, CONFIG_FILENAME)
38
+ if File.exist? user_cfg
39
+ temp = ParseConfig.new(user_cfg);
40
+ @config.params = @config.params.merge(temp.params)
41
+ end
42
+ end
43
+
33
44
  def self.reset
34
45
  @config = nil
35
46
  end
@@ -148,6 +148,7 @@ module CWG
148
148
  def word_count(wordcount)
149
149
  Cfg.config.params["word_count"] = wordcount
150
150
  @words.count wordcount
151
+ Cfg.config.params["words_counted"] = true
151
152
  end
152
153
 
153
154
  def beginning_with(* letters)
@@ -247,6 +248,7 @@ module CWG
247
248
 
248
249
  def run
249
250
  return if Cfg.config["no_run"]
251
+ word_count(Cfg.config["word_count"])unless Cfg.config.params["words_counted"]
250
252
  self.send run_default
251
253
  end
252
254
 
@@ -270,6 +272,15 @@ module CWG
270
272
  Cfg.config.params["use_ebook2cw"] = nil
271
273
  end
272
274
 
275
+ def callsign count = 1
276
+ callsign = Callsign.new
277
+ @words.assign callsign.* count
278
+ end
279
+
280
+ def read filename = :default
281
+ Read.new(filename)
282
+ end
283
+
273
284
  def words ; @words.all ; end
274
285
  def load_common_words ; @words.load 1000 ; end
275
286
  def load_most_common_words ; @words.load 500 ; end
@@ -4,71 +4,67 @@ module CWG
4
4
 
5
5
  class CwEncoding
6
6
 
7
- ENCODINGS = {
8
- 'a' => [:dot, :dash],
9
- 'b' => [:dash, :dot, :dot, :dot],
10
- 'c' => [:dash, :dot, :dash, :dot],
11
- 'd' => [:dash, :dot, :dot],
12
- 'e' => [:dot],
13
- 'f' => [:dot, :dot, :dash, :dot],
14
- 'g' => [:dash, :dash, :dot],
15
- 'h' => [:dot, :dot, :dot, :dot],
16
- 'i' => [:dot, :dot],
17
- 'j' => [:dot, :dash, :dash, :dash],
18
- 'k' => [:dash, :dot, :dash],
19
- 'l' => [:dot, :dash, :dot, :dot],
20
- 'm' => [:dash, :dash],
21
- 'n' => [:dash, :dot],
22
- 'o' => [:dash, :dash, :dash],
23
- 'p' => [:dot, :dash, :dash, :dot],
24
- 'q' => [:dash, :dash, :dot, :dash],
25
- 'r' => [:dot, :dash, :dot],
26
- 's' => [:dot, :dot, :dot],
27
- 't' => [:dash],
28
- 'u' => [:dot, :dot, :dash],
29
- 'v' => [:dot, :dot, :dot, :dash],
30
- 'w' => [:dot, :dash, :dash],
31
- 'x' => [:dash, :dot, :dot, :dash],
32
- 'y' => [:dash, :dot, :dash, :dash],
33
- 'z' => [:dash, :dash, :dot, :dot],
34
- '1' => [:dot, :dash, :dash, :dash, :dash],
35
- '2' => [:dot, :dot, :dash, :dash, :dash],
36
- '3' => [:dot, :dot, :dot, :dash, :dash],
37
- '4' => [:dot, :dot, :dot, :dot, :dash],
38
- '5' => [:dot, :dot, :dot, :dot, :dot],
39
- '6' => [:dash, :dot, :dot, :dot, :dot],
40
- '7' => [:dash, :dash, :dot, :dot, :dot],
41
- '8' => [:dash, :dash, :dash, :dot, :dot],
42
- '9' => [:dash, :dash, :dash, :dash, :dot],
43
- '0' => [:dash, :dash, :dash, :dash, :dash],
44
- '.' => [:dot, :dash, :dot, :dash, :dot, :dash],
45
- ',' => [:dash, :dash, :dot, :dot, :dash, :dash],
46
- '=' => [:dash, :dot, :dot,:dot, :dash],
47
- '!' => [:dot, :dot, :dash, :dash, :dot],
48
- '/' => [:dash, :dot, :dot, :dash, :dot],
49
- '?' => [:dot, :dot, :dash, :dash, :dot, :dot],
50
- ' ' => []
51
- }
7
+ include FileDetails
52
8
 
53
- def fetch char
54
- ENCODINGS[char]
9
+ def initialize
10
+ @char_lookup = "*eish54v*3uf***!2arl***+*wp**j*1tndb6=x/*kc**y**mgz7*q**o*8**90*".split('').map(&:to_sym)
55
11
  end
56
12
 
57
13
  def encodings
58
- ENCODINGS
14
+ if @encodings.nil?
15
+ @encodings = load_code
16
+ end
17
+ @encodings
18
+ end
19
+
20
+ def load_code
21
+ File.open(CODE_FILENAME, "r") do |code|
22
+ YAML::load(code)
23
+ end
24
+ end
25
+
26
+ def fetch char
27
+ encodings[char]
59
28
  end
60
29
 
61
30
  def match_elements arg
62
31
  chars = []
63
- ENCODINGS.each_pair do |key, value|
64
- chars << key unless value.include?(:dot) if arg[0] == :dashes
32
+ encodings.each_pair do |key, value|
33
+ chars << key unless value.include?(:dot) if arg[0] == :dashes
65
34
  chars << key unless value.include?(:dash) if arg[0] == :dots
66
- chars << key if (value.size < arg[1] )if arg[0] == :less_than
67
- chars << key if (value.size > arg[1] )if arg[0] == :greater_than
68
- chars << key if (value.size == arg[1] )if arg[0] == :size
35
+ chars << key if ( value.size < arg[1] ) if arg[0] == :less_than
36
+ chars << key if ( value.size > arg[1] ) if arg[0] == :greater_than
37
+ chars << key if ( value.size == arg[1] ) if arg[0] == :size
69
38
  chars.delete(' ')
70
39
  end
71
40
  chars
72
41
  end
42
+
43
+ def fast_match code
44
+ index = 0
45
+ dash_jump = 64
46
+ code.each do |ele|
47
+ # puts "ele: #{ele}"
48
+ dash_jump = dash_jump / 2
49
+ index = index + ((ele == :dot) ? 1 : dash_jump)
50
+ end
51
+ return @char_lookup[index].to_s
52
+ end
53
+
54
+ def fetch_char code
55
+ length = code.length
56
+ case length
57
+ when 1..5
58
+ return ' ' if code == [:space]
59
+ # return fast_match code
60
+ return encodings.key(code)
61
+ when 0
62
+ return '*'
63
+ else
64
+ temp = encodings.key(code)
65
+ return temp if temp
66
+ return '*' unless temp
67
+ end
68
+ end
73
69
  end
74
70
  end