pr2gpx 0.1.2 → 0.2.0

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/README.md CHANGED
@@ -1,18 +1,22 @@
1
1
  pr2gpx
2
2
  ======
3
3
 
4
- Converts Winlink position reports sent or received with Airmail into GPX tracks or waypoints.
4
+ Converts Winlink position reports into GPX tracks or waypoints.
5
5
 
6
- It understands:
6
+ pr2gpx understands position report data downloaded as RSS documents from the [Winlink 2000](http://www.winlink.org/) website using this Url:
7
+
8
+ http://www.winlink.org/dotnet/maps/RSSPositionReports.aspx?callsign=[callsign]
9
+
10
+ It also understands the information contained in messages sent or received with the [AirMail](http://siriuscyber.net/airmail/) client program:
7
11
  - sent position reports (Window->Winlink-2000->Position Report)
8
12
  - reports requested for specific stations (Window->Winlink-2000->Position Request)
9
13
  - lists of nearby stations (Window->Catalogs->WL2K->Global->WL2K_USERS->WL2K_NEARBY)
10
14
 
11
- pr2gpx scans a directory for files containing position reports in various formats. It can filter them to include only stations with a given callsign, and limit the results to the last N reports per station.
15
+ pr2gpx can either be given one file to parse, or it can scan all files in a directory. It can filter the data to include only stations with a given callsign, and limit the results to the last N reports per station.
12
16
 
13
17
  The output is either one track for each station, a list of waypoints for every position report, or both.
14
18
 
15
- This can either be saved into a single file containing everything, or it can be split into one file for each station.
19
+ The results can either be saved into a single file containing everything, or it can be split into one file for each station.
16
20
 
17
21
 
18
22
  Installing
data/lib/pr2gpx.rb CHANGED
@@ -9,9 +9,11 @@ def enumerate_files search_path
9
9
  Dir
10
10
  .glob(search_path)
11
11
  .each do |filename|
12
- $stderr.puts "Reading #{filename}" if $verbose
13
- File.open filename do |file|
14
- e.yield file.read()
12
+ if File.file?(filename)
13
+ $stderr.puts "Reading #{filename}" if $verbose
14
+ File.open filename do |file|
15
+ e.yield file.read()
16
+ end
15
17
  end
16
18
  end
17
19
  end
@@ -77,11 +79,16 @@ end
77
79
  options[:input].gsub!('\\', '/')
78
80
  options[:output].gsub!('\\', '/') if options[:output]
79
81
 
80
- search_path = "#{options[:input]}/#{options[:recurse] ? '**/' : ''}*.*"
81
- $stderr.puts "Searching #{search_path}" if $verbose
82
-
83
82
  filter = ReportFilter.new options[:callsign]
84
83
 
84
+ search_path = if File.directory?(options[:input])
85
+ "#{options[:input]}/#{options[:recurse] ? '**/' : ''}*.*"
86
+ else
87
+ options[:input]
88
+ end
89
+
90
+ $stderr.puts "Searching #{search_path}" if $verbose
91
+
85
92
  stations = load_data(enumerate_files(search_path), filter)
86
93
  filter_data! stations, options[:last]
87
94
 
@@ -104,8 +104,6 @@ def validate_options options
104
104
 
105
105
  if not File.exists?(options[:input])
106
106
  errors << 'Path specified in --input does not exist.'
107
- elsif not File.directory?(options[:input])
108
- errors << 'Path specified in --input is not a directory.'
109
107
  end
110
108
 
111
109
  if options[:split]
@@ -115,10 +113,12 @@ def validate_options options
115
113
  errors << 'Path specified in --output is not a directory.'
116
114
  end
117
115
  else
118
- if not File.exists?(File.dirname(options[:output]))
119
- errors << 'Path specified in --output does not exist.'
120
- elsif File.directory?(options[:output])
121
- errors << 'Path specified in --output is a directory.'
116
+ if options[:output]
117
+ if not File.exists?(File.dirname(options[:output]))
118
+ errors << 'Path specified in --output does not exist.'
119
+ elsif File.directory?(options[:output])
120
+ errors << 'Path specified in --output is a directory.'
121
+ end
122
122
  end
123
123
  end
124
124
 
data/lib/pr2gpx/parser.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require 'date'
2
+ require 'nokogiri'
3
+ require 'nokogiri/xml'
2
4
 
3
5
  PositionReport = Struct.new "PositionReport", :callsign, :date, :position, :comment
4
6
 
@@ -24,7 +26,7 @@ end
24
26
 
25
27
  class ReportParser
26
28
  def initialize
27
- @parsers = [NearbyStationsParser.new, ReportsListParser.new, OutboundReportParser.new]
29
+ @parsers = [NearbyStationsParser.new, ReportsListParser.new, OutboundReportParser.new, RSSParser.new]
28
30
  end
29
31
 
30
32
  def parse input
@@ -108,6 +110,34 @@ class NearbyStationsParser
108
110
  end
109
111
  end
110
112
 
113
+ class RSSParser
114
+ def can_parse? input
115
+ /<rss version="2\.0">/ =~ input
116
+ end
117
+
118
+ def parse input
119
+ Enumerator.new do |e|
120
+ xml = Nokogiri::XML(input)
121
+ xml.xpath('//item').each do |item|
122
+ %r{^
123
+ Position[ ]report[ ]for[ ]
124
+ (?<callsign>[^ ]*)
125
+ [ ]is[ ]
126
+ (?<latitude>[^ ]*)
127
+ [ ]/[ ]
128
+ (?<longitude>[^ ]*)
129
+ }x =~ item.xpath('title').first.content
130
+ comment = item.xpath('description').first.content
131
+ date = DateTime.parse(item.xpath('pubDate').first.content)
132
+ e.yield PositionReport.new callsign,
133
+ date,
134
+ Position.new(latitude, longitude),
135
+ comment
136
+ end
137
+ end
138
+ end
139
+ end
140
+
111
141
  class ReportFilter
112
142
  def initialize callsigns
113
143
  @callsigns = callsigns
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pr2gpx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-10-07 00:00:00.000000000 Z
12
+ date: 2012-10-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri