geoptima 0.0.4 → 0.0.5

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