Top Level Namespace

Defined Under Namespace

Classes: NearbyStationsParser, OutboundReportParser, Position, PositionReport, RSSParser, ReportFilter, ReportParser, ReportsListParser

Instance Method Summary collapse

Instance Method Details

#build_gpx(stations, create_trk, create_wpt) ⇒ Object

Creates the GPX document from the stations hash.

If create_trk is true, one trk per station gets created.

If create_wpt is true, one waypoint for every report of every station gets created.



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/pr2gpx/gpx.rb', line 10

def build_gpx stations, create_trk, create_wpt
  builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
    xml.gpx(xmlns: 'http://www.topografix.com/GPX/1/1') do
      if create_trk
        stations.each do |callsign, reports|
          xml.trk do
            xml.name callsign
            xml.trkseg do
              reports.each do |report|
                xml.send('trkpt', lat: report.position.latitude, lon: report.position.longitude) do
                  xml.name report.comment
                  xml.time report.date.strftime('%FT%TZ')
                end
              end
            end
          end
        end
      end
      if create_wpt
        stations.each do |callsign, reports|
          last = reports.last
          reports.each do |report|
            xml.send('wpt', lat: report.position.latitude, lon: report.position.longitude) do
              xml.name report.callsign
              xml.desc report.comment
              xml.time report.date.strftime('%FT%TZ')
              xml.type 'WPT'
              xml.sym report == last ? 'triangle' : 'circle'
            end
          end
        end
      end
    end
  end
  builder.to_xml
end

#enumerate_files(search_path) ⇒ Object

Creates an Enumerable with one entry for every file in search_path, containing the files content.



7
8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'lib/pr2gpx.rb', line 7

def enumerate_files search_path
  Enumerator.new do |e|
    Dir
      .glob(search_path)
      .each do |filename|
        if File.file?(filename)
          $stderr.puts "Reading #{filename}" if $verbose
          File.open filename do |file|
            e.yield file.read()
        end
      end
    end
  end
end

#filter_data!(stations, last) ⇒ Object

Converts the reports the entries of the stations-hash, which are hashes indexed by date, into arrays sorted by date.

The parameter last can be used to limit the reports to the N most recent ones.



57
58
59
60
61
62
63
64
65
66
67
# File 'lib/pr2gpx.rb', line 57

def filter_data! stations, last
  stations.each do |callsign, reports|
    stations[callsign] = reports.values
      .sort { |report1, report2| report1.date <=> report2.date }
    
    stations[callsign] = stations[callsign]
      .reverse
      .take(last)
      .reverse if last
  end
end

#load_data(content_enum, filter) ⇒ Object

Runs each element of content_enum through ReportParser::parse, receiving an Enumerable of PositionReport. If the report passes through the filter, it is added to the hash of the station, if no other report with the same date exists.

Those hashes are stored in another hash, indexed by callsign, which gets returned.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/pr2gpx.rb', line 29

def load_data content_enum, filter
  reportParser = ReportParser.new
  stations = Hash.new

  content_enum.each do |content|
    reports = reportParser.parse(content)
    if reports
      reports.each do |report|
        if filter.include? report
          $stderr.print 'o' if $verbose
          stations[report.callsign] = Hash.new unless stations.has_key? report.callsign
          stations[report.callsign][report.date] = report unless stations[report.callsign].has_key? report.date
        else
          $stderr.print '.' if $verbose
        end
      end
    end
    $stderr.puts if $verbose
  end

  stations
end

#parse_options(argv) ⇒ Object

If options are valid, returns a hash of options, otherwise nil.



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/pr2gpx/options.rb', line 4

def parse_options argv
  options = {}
  mandatory = []

  def set_option options, name
    ->(options, name, value) { options[name] = value }.curry.(options, name)
  end

  OptionParser.new do |o|
    options[:input] = nil
    o.on '-i', '--input [PATH]',
      'Specifies the path to be searched for files containing position reports.',
      set_option(options, :input)

    options[:recurse] = false
    o.on '-r', '--recurse',
      'Enables recursive searching.' do
        options[:recurse] = true
      end

    options[:output] = nil
    o.on '-o', '--output [PATH]',
      'Specifies the file or directory (when using --split) to write to. Default is STDOUT.',
      set_option(options, :output)

    options[:split] = false
    o.on '-s', '--split',
      'Creates one GPX document per station. If --output is specified, it is interpreted as a directory, and one file is created per station, named [PREFIX][STATION].gpx.' do |value|
      options[:split] = value
    end

    options[:prefix] = 'PR_'
    o.on '-p', '--prefix [PREFIX]',
      'Specifies the prefix to be used when using --split, default is \'PR_\'.',
      set_option(options, :output)

    options[:callsign] = nil
    o.on '-c', '--callsign [CALLSIGN[,CALLSIGN]]', Array,
      'Processes only the stations with the given callsigns.',
      set_option(options, :callsign)

    options[:last] = nil
    o.on '-l', '--last [n]', Integer,
      'Limits the result to the last N entries for each station.',
      set_option(options, :last)

    options[:help] = false
    o.on '-h', '--help',
      'Displays this screen.' do
      options[:help] = true
    end
    
    options[:create_trk] = options[:create_wpt] = true
    o.on '-f', '--format FORMAT[,FORMAT]', Array,
      'Selects one or more output formats. Supported values are \'TRK\', \'WPT\'.' do |values|
      values.each do |value|
        options[:create_trk] = options[:create_wpt] = false
        case(value)
          when 'TRK' then options[:create_trk] = true
          when 'WPT' then options[:create_wpt] = true
          else raise OptionParser::InvalidOption.new value
        end
      end
    end
    
    $verbose = false
    o.on '-v', '--verbose',
      'Turns on verbose mode.' do |value|
      $verbose = value
    end

    begin
      o.parse! argv

      if not options[:help]
        missing = mandatory.select { |param| options[param].nil? }
        if not missing.empty?
          puts "Missing options: #{missing.join(', ')}"
          puts
          options[:help] = true
        end
      end
    rescue OptionParser::InvalidOption, OptionParser::MissingArgument
      puts $!.to_s
      puts
      options[:help] = true
    end

    if options[:help]
      puts o
      return nil
    end
  end

  options
end

#set_option(options, name) ⇒ Object



8
9
10
# File 'lib/pr2gpx/options.rb', line 8

def set_option options, name
  ->(options, name, value) { options[name] = value }.curry.(options, name)
end

#validate_options(options) ⇒ Object

If errors are encountered, returns an array of error messages, otherwise nil.



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/pr2gpx/options.rb', line 102

def validate_options options
  errors = []

  if options[:input]
    if not File.exists?(options[:input])
      errors << 'Path specified in --input does not exist.'
    end
  end

  if options[:split]
    if not File.exists?(options[:output])
      errors << 'Path specified in --output does not exist.'
    elsif not File.directory?(options[:output])
      errors << 'Path specified in --output is not a directory.'
    end
  else
    if options[:output]
      if not File.exists?(File.dirname(options[:output]))
        errors << 'Path specified in --output does not exist.'
      elsif File.directory?(options[:output])
        errors << 'Path specified in --output is a directory.'
      end
    end
  end

  errors if errors.length > 0
end

#write_gpx(filename, gpx) ⇒ Object

Writes the gpx document with UTF-8 encoding to filename.



48
49
50
51
52
53
# File 'lib/pr2gpx/gpx.rb', line 48

def write_gpx filename, gpx
  $stderr.puts "Writing #{filename}" if $verbose
  File.open filename, 'w:UTF-8' do |file|
    file.write gpx
  end
end