geoptima 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/geoptima_file_time +10 -0
- data/bin/show_geoptima +45 -4
- data/examples/geoptima_file_time.rb +10 -0
- data/examples/show_geoptima.rb +45 -4
- data/geoptima.gemspec +4 -3
- data/lib/geoptima/data.rb +46 -25
- data/lib/geoptima/version.rb +1 -1
- metadata +7 -6
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.
|
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(
|
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.
|
198
|
-
|
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/examples/show_geoptima.rb
CHANGED
@@ -7,7 +7,7 @@ $: << '../lib'
|
|
7
7
|
require 'date'
|
8
8
|
require 'geoptima'
|
9
9
|
|
10
|
-
Geoptima::assert_version("0.0.
|
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(
|
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.
|
198
|
-
|
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
|
-
|
28
|
+
s.executables = ['show_geoptima','geoptima_file_time']
|
29
|
+
|
30
30
|
s.extra_rdoc_files = %w( README.rdoc )
|
31
|
-
s.rdoc_options = ["--quiet", "--title", "
|
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: #{
|
104
|
-
puts "\tMNC: #{
|
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
|
118
|
-
@
|
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
|
241
|
-
a[d
|
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
|
-
|
273
|
+
self['Platform']
|
253
274
|
end
|
254
275
|
|
255
276
|
def model
|
256
|
-
|
277
|
+
self['Model']
|
257
278
|
end
|
258
279
|
|
259
280
|
def os
|
260
|
-
|
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
|
364
|
-
datasets[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
|
data/lib/geoptima/version.rb
CHANGED
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:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
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
|
-
-
|
75
|
-
- --opname
|
76
|
-
- index.html
|
77
|
+
- Geoptima.rb
|
77
78
|
- --line-numbers
|
78
79
|
- --main
|
79
80
|
- README.rdoc
|