cw 0.3.0 → 0.3.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.
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