pr2gpx 0.1.2 → 0.2.0

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