geoptima 0.0.4 → 0.0.5

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.
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'date'
4
+
5
+ $root=DateTime.parse("1970-01-01 00:00:00")
6
+ ARGV.each do |arg|
7
+ base,seconds=arg.split(/_/)
8
+ date = ($root + seconds.to_f/(60*60*24))
9
+ puts "#{date}\t#{arg}"
10
+ end
data/bin/show_geoptima CHANGED
@@ -7,7 +7,7 @@ $: << '../lib'
7
7
  require 'date'
8
8
  require 'geoptima'
9
9
 
10
- Geoptima::assert_version("0.0.3")
10
+ Geoptima::assert_version("0.0.5")
11
11
 
12
12
  $debug=false
13
13
 
@@ -39,6 +39,8 @@ while arg=ARGV.shift do
39
39
  $export_stats=true
40
40
  when 'm'
41
41
  $map_headers=true
42
+ when 'l'
43
+ $more_headers=true
42
44
  when 'E'
43
45
  $event_names += ARGV.shift.split(/[\,\;\:\.]+/)
44
46
  when 'T'
@@ -71,6 +73,7 @@ Usage: ./showGeoptimaEvents.rb <-dvxEh> <-L limit> <-E types> <-T min,max> file
71
73
  -x export IMEI specific CSV files for further processing #{cw $export}
72
74
  -o export field statistis #{cw $export_stats}
73
75
  -m map headers to classic NetView compatible version #{cw $map_headers}
76
+ -l longer header list (phone and operator fields) #{cw $more_headers}
74
77
  -s seperate the export files by event type #{cw $seperate}
75
78
  -h show this help
76
79
  -L limit verbose output to specific number of lines #{cw $print_limit}
@@ -86,6 +89,7 @@ $datasets = Geoptima::Dataset.make_datasets($files, :locate => true, :time_range
86
89
  class Export
87
90
  attr_reader :files, :imei, :names, :headers
88
91
  def initialize(imei,names,dataset)
92
+ imei = dataset.imsi if(imei.to_s.length < 1)
89
93
  @imei = imei
90
94
  @names = names
91
95
  if $export
@@ -106,7 +110,7 @@ class Export
106
110
  end
107
111
  @headers[nil] = @headers.values.flatten
108
112
  files && files.each do |key,file|
109
- file.puts map_headers(['Time','Event','Latitude','Longitude','IMSI','IMEI']+header(key)).join("\t")
113
+ file.puts map_headers(base_headers+more_headers+header(key)).join("\t")
110
114
  end
111
115
  if $debug || $verbose
112
116
  @headers.each do |name,head|
@@ -114,6 +118,42 @@ class Export
114
118
  end
115
119
  end
116
120
  end
121
+ def base_headers
122
+ ['Time','Event','Latitude','Longitude']
123
+ end
124
+ def more_headers
125
+ $more_headers ? ['IMSI','IMEI','MSISDN','MCC','MNC','LAC','CI','RSSI','Platform','Model','OS','Operator'] : []
126
+ end
127
+ def base_fields(event)
128
+ [event.time_key,event.name,event.latitude,event.longitude]
129
+ end
130
+ def more_fields(event,dataset)
131
+ more_headers.map do |h|
132
+ case h
133
+ when 'RSSI'
134
+ dataset.recent(event,'signal.strength')
135
+ when 'LAC'
136
+ dataset.recent(event,'service.lac')
137
+ when 'CI'
138
+ dataset.recent(event,'service.cell_id')
139
+ when 'MCC'
140
+ dataset[h] || dataset.recent(event,'service.mcc')
141
+ when 'MNC'
142
+ dataset[h] || dataset.recent(event,'service.mnc')
143
+ when 'Operator'
144
+ dataset['carrierName']
145
+ when 'IMSI'
146
+ dataset.imsi
147
+ when 'IMEI'
148
+ dataset.imei
149
+ else
150
+ dataset[h]
151
+ end
152
+ end
153
+ end
154
+ def get_field(event,name)
155
+ h=(base_headers+more_headers).grep(/#{name}/)
156
+ end
117
157
  def cap(array,sep="")
118
158
  array.map do |v|
119
159
  "#{v[0..0].upcase}#{v[1..-1]}"
@@ -194,8 +234,9 @@ $datasets.keys.sort.each do |imei|
194
234
  names.each do |name|
195
235
  if event.name === name
196
236
  fields = export.header($seperate ? name : nil).map{|h| event[h]}
197
- export.puts_to "#{event.time_key}\t#{event.name}\t#{event.latitude}\t#{event.longitude}\t#{imsi}\t#{imei}\t#{fields.join("\t")}", name
198
- if_le{puts "#{event.time_key}\t#{event.name}\t#{event.latitude}\t#{event.longitude}\t#{imsi}\t#{imei}\t#{event.fields.inspect}"}
237
+ b_fields = export.base_fields(event) + export.more_fields(event,dataset)
238
+ export.puts_to "#{b_fields.join("\t")}\t#{fields.join("\t")}", name
239
+ if_le{puts "#{b_fields.join("\t")}\t#{event.fields.inspect}"}
199
240
  end
200
241
  end
201
242
  end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'date'
4
+
5
+ $root=DateTime.parse("1970-01-01 00:00:00")
6
+ ARGV.each do |arg|
7
+ base,seconds=arg.split(/_/)
8
+ date = ($root + seconds.to_f/(60*60*24))
9
+ puts "#{date}\t#{arg}"
10
+ end
@@ -7,7 +7,7 @@ $: << '../lib'
7
7
  require 'date'
8
8
  require 'geoptima'
9
9
 
10
- Geoptima::assert_version("0.0.4")
10
+ Geoptima::assert_version("0.0.5")
11
11
 
12
12
  $debug=false
13
13
 
@@ -39,6 +39,8 @@ while arg=ARGV.shift do
39
39
  $export_stats=true
40
40
  when 'm'
41
41
  $map_headers=true
42
+ when 'l'
43
+ $more_headers=true
42
44
  when 'E'
43
45
  $event_names += ARGV.shift.split(/[\,\;\:\.]+/)
44
46
  when 'T'
@@ -71,6 +73,7 @@ Usage: ./showGeoptimaEvents.rb <-dvxEh> <-L limit> <-E types> <-T min,max> file
71
73
  -x export IMEI specific CSV files for further processing #{cw $export}
72
74
  -o export field statistis #{cw $export_stats}
73
75
  -m map headers to classic NetView compatible version #{cw $map_headers}
76
+ -l longer header list (phone and operator fields) #{cw $more_headers}
74
77
  -s seperate the export files by event type #{cw $seperate}
75
78
  -h show this help
76
79
  -L limit verbose output to specific number of lines #{cw $print_limit}
@@ -86,6 +89,7 @@ $datasets = Geoptima::Dataset.make_datasets($files, :locate => true, :time_range
86
89
  class Export
87
90
  attr_reader :files, :imei, :names, :headers
88
91
  def initialize(imei,names,dataset)
92
+ imei = dataset.imsi if(imei.to_s.length < 1)
89
93
  @imei = imei
90
94
  @names = names
91
95
  if $export
@@ -106,7 +110,7 @@ class Export
106
110
  end
107
111
  @headers[nil] = @headers.values.flatten
108
112
  files && files.each do |key,file|
109
- file.puts map_headers(['Time','Event','Latitude','Longitude','IMSI','IMEI']+header(key)).join("\t")
113
+ file.puts map_headers(base_headers+more_headers+header(key)).join("\t")
110
114
  end
111
115
  if $debug || $verbose
112
116
  @headers.each do |name,head|
@@ -114,6 +118,42 @@ class Export
114
118
  end
115
119
  end
116
120
  end
121
+ def base_headers
122
+ ['Time','Event','Latitude','Longitude']
123
+ end
124
+ def more_headers
125
+ $more_headers ? ['IMSI','IMEI','MSISDN','MCC','MNC','LAC','CI','RSSI','Platform','Model','OS','Operator'] : []
126
+ end
127
+ def base_fields(event)
128
+ [event.time_key,event.name,event.latitude,event.longitude]
129
+ end
130
+ def more_fields(event,dataset)
131
+ more_headers.map do |h|
132
+ case h
133
+ when 'RSSI'
134
+ dataset.recent(event,'signal.strength')
135
+ when 'LAC'
136
+ dataset.recent(event,'service.lac')
137
+ when 'CI'
138
+ dataset.recent(event,'service.cell_id')
139
+ when 'MCC'
140
+ dataset[h] || dataset.recent(event,'service.mcc')
141
+ when 'MNC'
142
+ dataset[h] || dataset.recent(event,'service.mnc')
143
+ when 'Operator'
144
+ dataset['carrierName']
145
+ when 'IMSI'
146
+ dataset.imsi
147
+ when 'IMEI'
148
+ dataset.imei
149
+ else
150
+ dataset[h]
151
+ end
152
+ end
153
+ end
154
+ def get_field(event,name)
155
+ h=(base_headers+more_headers).grep(/#{name}/)
156
+ end
117
157
  def cap(array,sep="")
118
158
  array.map do |v|
119
159
  "#{v[0..0].upcase}#{v[1..-1]}"
@@ -194,8 +234,9 @@ $datasets.keys.sort.each do |imei|
194
234
  names.each do |name|
195
235
  if event.name === name
196
236
  fields = export.header($seperate ? name : nil).map{|h| event[h]}
197
- export.puts_to "#{event.time_key}\t#{event.name}\t#{event.latitude}\t#{event.longitude}\t#{imsi}\t#{imei}\t#{fields.join("\t")}", name
198
- if_le{puts "#{event.time_key}\t#{event.name}\t#{event.latitude}\t#{event.longitude}\t#{imsi}\t#{imei}\t#{event.fields.inspect}"}
237
+ b_fields = export.base_fields(event) + export.more_fields(event,dataset)
238
+ export.puts_to "#{b_fields.join("\t")}\t#{fields.join("\t")}", name
239
+ if_le{puts "#{b_fields.join("\t")}\t#{event.fields.inspect}"}
199
240
  end
200
241
  end
201
242
  end
data/geoptima.gemspec CHANGED
@@ -25,10 +25,11 @@ EOF
25
25
  s.files = Dir.glob("{bin,lib,rdoc}/**/*").reject{|x| x=~/(tmp|target|test-data)/ || x=~/~$/} +
26
26
  Dir.glob("examples/*rb") + Dir.glob("examples/sample*json") +
27
27
  %w(README.rdoc CHANGELOG CONTRIBUTORS Gemfile geoptima.gemspec)
28
- s.executables = ['show_geoptima']
29
- s.has_rdoc = true
28
+ s.executables = ['show_geoptima','geoptima_file_time']
29
+
30
30
  s.extra_rdoc_files = %w( README.rdoc )
31
- s.rdoc_options = ["--quiet", "--title", "geoptima.rb", "--opname", "index.html", "--line-numbers", "--main", "README.rdoc", "--inline-source"]
31
+ s.rdoc_options = ["--quiet", "--title", "Geoptima.rb", "--line-numbers", "--main", "README.rdoc", "--inline-source"]
32
+
32
33
  s.add_dependency('json',">= 1.6.5")
33
34
  s.required_ruby_version = ">= 1.8.6"
34
35
  end
data/lib/geoptima/data.rb CHANGED
@@ -71,6 +71,9 @@ module Geoptima
71
71
  def [](key)
72
72
  @fields[key] || @fields[key.gsub(/#{name}\./,'')]
73
73
  end
74
+ def []=(key,value)
75
+ @fields[key] ||= value
76
+ end
74
77
  def -(other)
75
78
  (self.time - other.time) * SPERDAY
76
79
  end
@@ -95,13 +98,14 @@ module Geoptima
95
98
  def initialize(path)
96
99
  @path = path
97
100
  @json = JSON.parse(File.read(path))
101
+ @fields = {}
98
102
  if $debug
99
103
  puts "Read Geoptima: #{geoptima.to_json}"
100
104
  puts "\tSubscriber: #{subscriber.to_json}"
101
- puts "\tIMSI: #{imsi}"
102
- puts "\tIMEI: #{imei}"
103
- puts "\tMCC: #{subscriber['MCC']}"
104
- puts "\tMNC: #{subscriber['MNC']}"
105
+ puts "\tIMSI: #{self['imsi']}"
106
+ puts "\tIMEI: #{self['imei']}"
107
+ puts "\tMCC: #{self['MCC']}"
108
+ puts "\tMNC: #{self['MNC']}"
105
109
  puts "\tStart: #{start}"
106
110
  end
107
111
  end
@@ -114,20 +118,8 @@ module Geoptima
114
118
  def subscriber
115
119
  @subscriber ||= geoptima['subscriber']
116
120
  end
117
- def imsi
118
- @imsi ||= subscriber['imsi']
119
- end
120
- def imei
121
- @imei ||= subscriber['imei']
122
- end
123
- def platform
124
- @platform ||= subscriber['Platform'] || subscriber['platform']
125
- end
126
- def model
127
- @model ||= subscriber['Model'] || subscriber['model']
128
- end
129
- def os
130
- @os ||= subscriber['OS']
121
+ def [](key)
122
+ @fields[key] ||= subscriber[key] || subscriber[key.downcase]
131
123
  end
132
124
  def start
133
125
  @start ||= subscriber['start'] && DateTime.parse(subscriber['start'].gsub(/Asia\/Bangkok/,'GMT+7').gsub(/Mar 17 2044/,'Feb 14 2012'))
@@ -220,6 +212,7 @@ module Geoptima
220
212
  @data = []
221
213
  @options = options
222
214
  @time_range = options[:time_range] || Range.new(Config[:min_datetime],Config[:max_datetime])
215
+ @fields = {}
223
216
  end
224
217
 
225
218
  def <<(data)
@@ -237,8 +230,8 @@ module Geoptima
237
230
 
238
231
  def imsis
239
232
  @imsis ||= @data.inject({}) do |a,d|
240
- a[d.imsi] ||= 0
241
- a[d.imsi] += d.count.to_i
233
+ a[d['imsi']] ||= 0
234
+ a[d['imsi']] += d.count.to_i
242
235
  a
243
236
  end.to_a.sort do |a,b|
244
237
  b[1]<=>a[1]
@@ -248,16 +241,44 @@ module Geoptima
248
241
  end.compact.uniq
249
242
  end
250
243
 
244
+ def recent(event,key)
245
+ unless event[key]
246
+ puts "Searching for recent values for '#{key}' starting at event #{event}" if($debug)
247
+ ev,prop=key.split(/\./)
248
+ ar=sorted
249
+ puts "\tSearching through #{ar && ar.length} events for event type #{ev} and property #{prop}" if($debug)
250
+ if i=ar.index(event)
251
+ afe = while(i>0)
252
+ fe = ar[i-=1]
253
+ puts "\t\tTesting event[#{i}]: #{fe}" if($debug)
254
+ break(fe) if(fe.nil? || fe.name == ev || (event.time - fe.time) * SPERDAY > 60)
255
+ end
256
+ if afe && afe.name == ev
257
+ puts "\t\tFound event[#{i}] with #{prop} => #{afe[prop]} and time gap of #{(event.time - fe.time) * SPERDAY} seconds" if($verbose)
258
+ event[key] = afe[prop]
259
+ end
260
+ else
261
+ puts "Event not found in search for recent '#{key}': #{event}"
262
+ end
263
+ end
264
+ # @recent[key] ||= ''
265
+ event[key]
266
+ end
267
+
268
+ def [](key)
269
+ @fields[key.downcase] ||= @data.map{|d| d[key]}.compact.uniq[0]
270
+ end
271
+
251
272
  def platform
252
- @platform ||= @data.map{|d| d.platform}.compact.uniq[0]
273
+ self['Platform']
253
274
  end
254
275
 
255
276
  def model
256
- @model ||= @data.map{|d| d.model}.compact.uniq[0]
277
+ self['Model']
257
278
  end
258
279
 
259
280
  def os
260
- @os ||= @data.map{|d| d.os}.compact.uniq[0]
281
+ self['OS']
261
282
  end
262
283
 
263
284
  def first
@@ -360,8 +381,8 @@ module Geoptima
360
381
  unless geoptima.valid?
361
382
  puts "INVALID: #{geoptima.start}\t#{file}\n\n"
362
383
  else
363
- datasets[geoptima.imei] ||= Geoptima::Dataset.new(geoptima.imei, options)
364
- datasets[geoptima.imei] << geoptima
384
+ datasets[geoptima['imei']] ||= Geoptima::Dataset.new(geoptima['imei'], options)
385
+ datasets[geoptima['imei']] << geoptima
365
386
  end
366
387
  end
367
388
  datasets
@@ -1,6 +1,6 @@
1
1
  module Geoptima
2
2
 
3
- VERSION = "0.0.4"
3
+ VERSION = "0.0.5"
4
4
 
5
5
  def self.version_as_int(ver)
6
6
  base = 1
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: geoptima
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
4
+ hash: 21
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 4
10
- version: 0.0.4
9
+ - 5
10
+ version: 0.0.5
11
11
  platform: ruby
12
12
  authors:
13
13
  - Craig Taverner
@@ -45,12 +45,14 @@ description: |
45
45
  email: craig@amanzi.com
46
46
  executables:
47
47
  - show_geoptima
48
+ - geoptima_file_time
48
49
  extensions: []
49
50
 
50
51
  extra_rdoc_files:
51
52
  - README.rdoc
52
53
  files:
53
54
  - bin/show_geoptima
55
+ - bin/geoptima_file_time
54
56
  - lib/geoptima/version.rb
55
57
  - lib/geoptima/data.rb
56
58
  - lib/geoptima.rb
@@ -58,6 +60,7 @@ files:
58
60
  - examples/export_layer.rb
59
61
  - examples/stats.rb
60
62
  - examples/show_geoptima.rb
63
+ - examples/geoptima_file_time.rb
61
64
  - examples/sample_geoptima.json
62
65
  - README.rdoc
63
66
  - CHANGELOG
@@ -71,9 +74,7 @@ post_install_message:
71
74
  rdoc_options:
72
75
  - --quiet
73
76
  - --title
74
- - geoptima.rb
75
- - --opname
76
- - index.html
77
+ - Geoptima.rb
77
78
  - --line-numbers
78
79
  - --main
79
80
  - README.rdoc