ClickSpotter 0.1.1

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,120 @@
1
+ #
2
+ # LogParser.rb - ClickSpotter
3
+ #
4
+ # Copyright (c) 2005, 2006 by Chris Schlaeger <cs@kde.org>
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of version 2 of the GNU General Public License as
7
+ # published by the Free Software Foundation.
8
+ #
9
+ # $Id: LogParser.rb 9 2006-01-23 08:41:35Z cs $
10
+ #
11
+
12
+ class LogParser
13
+
14
+ def initialize()
15
+ @fileName = nil
16
+ @stream = nil
17
+ end
18
+
19
+ def setFileName(fileName)
20
+ return if fileName == @fileName
21
+ if @stream != nil
22
+ @stream.close
23
+ @progressDlg = nil
24
+ @stream = nil
25
+ end
26
+ @fileName = fileName
27
+ end
28
+
29
+ def getNextEntry(deadline)
30
+ # Make sure the file is open for reading. If not, open it and setup
31
+ # a progress dialog in case it's a big file.
32
+ if @stream == nil
33
+ @stream = File.new(@fileName, 'r')
34
+ @progressDlg = Qt::ProgressDialog.new(nil, nil, true)
35
+ @progressDlg.setLabelText("Loading file #{@fileName} ...")
36
+ @sizeAtOpen = File.size(@fileName)
37
+ @progressDlg.setTotalSteps(@sizeAtOpen)
38
+ @updateCounter = 0
39
+ end
40
+
41
+ # Update the progress dialog (even when it's not shown)
42
+ if @progressDlg != nil
43
+ if @stream.pos() >= @sizeAtOpen
44
+ @progressDlg.setProgress(@sizeAtOpen)
45
+ @progressDlg = nil
46
+ else
47
+ @updateCounter += 1
48
+ @progressDlg.setProgress(@stream.pos()) if @updateCounter % 100 == 0
49
+ end
50
+ end
51
+
52
+ # read one line from log and process it. Ignore all lines that are older
53
+ # than the requested deadline
54
+ begin
55
+ line = @stream.gets
56
+ if line == nil
57
+ return nil
58
+ end
59
+ tokens = line.chomp().split(' ')
60
+ if tokens.size < 10
61
+ puts "Discarding corrupted log line: #{line}"
62
+ next
63
+ end
64
+ ip = tokens[0]
65
+ uid = tokens[1]
66
+ timeStr = tokens[3].gsub(/[\[]/, '').gsub(/\//, ' ').sub(/:/, ' ')
67
+ begin
68
+ timeStamp = Time.parse(timeStr)
69
+ rescue
70
+ puts "Broken timestamp: #{line}"
71
+ timeStamp = 0
72
+ next
73
+ end
74
+ end while timeStamp < deadline
75
+
76
+ request = tokens[5] + ' ' + tokens[6] + ' ' + tokens[7]
77
+ isPage = false
78
+ if tokens[5].sub(/"/, '') == 'GET'
79
+ url = tokens[6]
80
+ url = '/' if url == nil || url.empty?
81
+ # Remove trailing slashes except for the base page
82
+ url = url[0..-2] if url[-1..-1] == '/' && url != '/'
83
+
84
+ if not $globals.isAuxFile(url)
85
+ isPage = true
86
+ end
87
+ else
88
+ url = nil
89
+ end
90
+ request.gsub!(/"/, '')
91
+ code = tokens[8].to_i
92
+ bytes = tokens[9].to_i
93
+ referer = tokens[10] ? tokens[10].gsub(/"/, '') : ''
94
+ # Remove the local server name from local referer URLs
95
+ $globals.serverNames.each do |name|
96
+ if referer.length >= name.length &&
97
+ referer.slice(0 , name.length) == name
98
+ referer = referer.slice(name.length,
99
+ referer.length - name.length)
100
+ end
101
+ end
102
+ # Remove trailing slashes except for the base page
103
+ referer = referer[0..-2] if !referer.empty? && referer[-1..-1] == '/' && \
104
+ referer != '/'
105
+ referer = nil if referer == '-'
106
+
107
+ if tokens[11]
108
+ browser = tokens[11..tokens.length() - 1].join(' ').gsub(/"/, '')
109
+ else
110
+ browser = ''
111
+ end
112
+
113
+ return {
114
+ 'ip' => ip, 'uid' => uid, 'timeStamp' => timeStamp, 'request' => request,
115
+ 'url' => url, 'code' => code, 'bytes' => bytes,
116
+ 'referer' => referer, 'browser' => browser, 'isPage' => isPage}
117
+ end
118
+
119
+ end
120
+
@@ -0,0 +1,627 @@
1
+ #
2
+ # MainWindow.rb - ClickSpotter
3
+ #
4
+ # Copyright (c) 2005, 2006 by Chris Schlaeger <cs@kde.org>
5
+ # This program is free software; you can redistribute it and/or modify
6
+ # it under the terms of version 2 of the GNU General Public License as
7
+ # published by the Free Software Foundation.
8
+ #
9
+ # $Id: MainWindow.rb 10 2006-01-23 14:29:58Z cs $
10
+ #
11
+
12
+ require 'Qt'
13
+ require 'time'
14
+ require 'GlobalSettings'
15
+ require 'GeoLocator'
16
+ require 'DNSResolver'
17
+ require 'MainWindowDlg'
18
+ require 'LogFileSelector'
19
+ require 'About'
20
+ require 'ServerLogSettings'
21
+ require 'VisitorInformation'
22
+ require 'PageInformation'
23
+ require 'RefererInformation'
24
+ require 'LogParser'
25
+ require 'HitRecord'
26
+ require 'VisitorRecord'
27
+ require 'PageRecord'
28
+ require 'RefererRecord'
29
+ require 'StatusCode'
30
+ require 'OccurenceCounter'
31
+ require 'Configuration'
32
+ require 'GeoDistView'
33
+ require 'BrowserLauncher'
34
+ require 'CSListView'
35
+
36
+ PurgeInterval = 20
37
+
38
+ class MainWindow < MainWindowDlg
39
+
40
+ include BrowserLauncher
41
+
42
+ slots 'update()', 'updateTab(QWidget*)', 'clearVisitorFilter()',
43
+ 'clearPageFilter()', 'clearRefererFilter()',
44
+ 'recentHostClicked(QListViewItem*)',
45
+ 'topPageClicked(QListViewItem*)',
46
+ 'topRefererClicked(QListViewItem*)',
47
+ 'hostClicked(QListViewItem*)',
48
+ 'pageClicked(QListViewItem*)',
49
+ 'refererClicked(QListViewItem*)',
50
+ 'tabChanged(QWidget*)'
51
+
52
+ def initialize(parent = nil, name = nil)
53
+ super
54
+ init
55
+ $windowList = []
56
+ $windowList.push(self)
57
+ @log = LogParser.new
58
+ @nextPurge = Time.now + PurgeInterval
59
+
60
+ @currentGDV = GeoDistView.new(@currentMapFrame, currentCountryList)
61
+
62
+ @hostListCSLV = CSListView.new(@hostList)
63
+ # Setup the columns of the "Current Status" list view
64
+ @hostList.setSorting(2, false)
65
+ @hostListCSLV.setColumnWidth(0, 300)
66
+ @hostListCSLV.setColumnWidth(3, 450)
67
+ @hostListCSLV.setColumnWidth(4, 120)
68
+ @hostListCSLV.setColumnWidth(5, 200)
69
+
70
+ @topPageListCSLV = CSListView.new(topPageList)
71
+ # Setup the columns of the "Top Pages" list view
72
+ @topPageList.setSorting(1, false)
73
+ @topPageListCSLV.setColumnWidth(0, 500)
74
+
75
+ @topRefererListCSLV = CSListView.new(topRefererList)
76
+ # Setup the columns of the "Top Referers" list view
77
+ @topRefererList.setSorting(1, false)
78
+ @topRefererListCSLV.setColumnWidth(0, 500)
79
+
80
+ @visitorGDV = GeoDistView.new(@visitorMapFrame, @visitorCountryList)
81
+ @fullHostListCSLV = CSListView.new(@fullHostList)
82
+ # Setup the columns of the "Visitors" list view
83
+ @fullHostList.setSorting(2, false)
84
+ @fullHostListCSLV.setColumnWidth(0, 300)
85
+ @fullHostListCSLV.setColumnWidth(3, 450)
86
+
87
+ @visitorWorldMap = nil
88
+
89
+ @pageListCSLV = CSListView.new(@pageList)
90
+ # Setup the columns of the "Pages" list view
91
+ @pageList.setSorting(1, false)
92
+ @pageListCSLV.setColumnWidth(0, 500)
93
+
94
+ @refererListCSLV = CSListView.new(@refererList)
95
+ # Setup the columns on the "Referer" list view
96
+ @refererList.setSorting(1, false)
97
+ @refererListCSLV.setColumnWidth(0, 500)
98
+
99
+ @statusCodeListCSLV = CSListView.new(@statusCodeList)
100
+ # Setup the columns of the "Status Code" list view
101
+ @statusCodeList.setSorting(0, true)
102
+
103
+ @hitListCSLV = CSListView.new(@hitList)
104
+ # Setup the columns of the "Hit" list view
105
+ @hitList.setSorting(0, false)
106
+
107
+ connect(@tabWidget, SIGNAL('currentChanged(QWidget*)'),
108
+ SLOT('tabChanged(QWidget*)'))
109
+ connect(@hostList, SIGNAL('clicked(QListViewItem*)'),
110
+ SLOT('recentHostClicked(QListViewItem*)'))
111
+ connect(@topPageList, SIGNAL('clicked(QListViewItem*)'),
112
+ SLOT('topPageClicked(QListViewItem*)'))
113
+ connect(@topRefererList, SIGNAL('clicked(QListViewItem*)'),
114
+ SLOT('topRefererClicked(QListViewItem*)'))
115
+ connect(@fullHostList, SIGNAL('clicked(QListViewItem*)'),
116
+ SLOT('hostClicked(QListViewItem*)'))
117
+ connect(@pageList, SIGNAL('clicked(QListViewItem*)'),
118
+ SLOT('pageClicked(QListViewItem*)'))
119
+ connect(@refererList, SIGNAL('clicked(QListViewItem*)'),
120
+ SLOT('refererClicked(QListViewItem*)'))
121
+
122
+ connect(@clearVisitorFilterBtn, SIGNAL('clicked()'),
123
+ SLOT('clearVisitorFilter()'))
124
+ connect(@clearPageFilterBtn, SIGNAL('clicked()'),
125
+ SLOT('clearPageFilter()'))
126
+ connect(@clearRefererFilterBtn, SIGNAL('clicked()'),
127
+ SLOT('clearRefererFilter()'))
128
+ connect(@tabWidget, SIGNAL('currentChanged(QWidget*)'),
129
+ SLOT('updateTab(QWidget*)'))
130
+
131
+ @updateTimer = Qt::Timer.new(self)
132
+ connect(@updateTimer, SIGNAL('timeout()'), SLOT('update()'))
133
+ @updateTimer.start(500)
134
+
135
+ if $globals.getSetting("MainWindowW") > 0 &&
136
+ $globals.getSetting("MainWindowH") > 0
137
+ resize($globals.getSetting("MainWindowW"),
138
+ $globals.getSetting("MainWindowH"))
139
+ end
140
+
141
+ setMonitorWindow($globals.getSetting("MonitorWindow"))
142
+ @showRegularPages.setOn($globals.getSetting("ShowRegularPages") != 0)
143
+ @showAuxPages.setOn($globals.getSetting("ShowAuxPages") != 0)
144
+ @showSurfers.setOn($globals.getSetting("ShowSurfers") != 0)
145
+ @showRobots.setOn($globals.getSetting("ShowRobots") != 0)
146
+
147
+ updateWindow()
148
+ show
149
+ end
150
+
151
+ def init
152
+ $hitRecords = []
153
+ $visitors = {}
154
+ $pages = {}
155
+ $referers = {}
156
+ $statusCodes = {}
157
+ $recentVisitors = OccurenceCounter.new(50)
158
+ $recentPages = OccurenceCounter.new(30)
159
+ $recentReferers = OccurenceCounter.new(15)
160
+ end
161
+
162
+ def close(dummy)
163
+ @visitorWorldMap.close(true) if @visitorWorldMap
164
+ @visitorWorldMap = nil
165
+
166
+ $resolver.stopAndSave
167
+ $geoLocator.stopAndSave
168
+ $traceRouter.stopAndSave
169
+
170
+ $windowList.delete(self)
171
+ $globals.setSetting("MainWindowW", width())
172
+ $globals.setSetting("MainWindowH", height())
173
+ #$globals.currentStatusSplitter = @currentStatusSplitter.sizes()
174
+ $globals.saveSettings()
175
+ super(true)
176
+ end
177
+
178
+ def tabChanged(dummy)
179
+ # Some pages generate excessive requests when started with a large
180
+ # fresh log file. These requests are discarded when the requesting
181
+ # page is no longer viewed.
182
+ $resolver.flushQueue
183
+ $geoLocator.flushQueue
184
+ $traceRouter.flushQueue
185
+ end
186
+
187
+ def fileExit()
188
+ close(true)
189
+ end
190
+
191
+ def setMonitorWindow(duration)
192
+ actionList = { 1 => @mw_1, 2 => @mw_2, 5 => @mw_5, 10 => @mw_10,
193
+ 20 => @mw_20, 30 => @mw_30, 60 => @mw_60, 120 => @mw_120 }
194
+ actionList.each_value { |a| a.setOn(false) }
195
+ actionList[duration].setOn(true)
196
+ $globals.setSetting("MonitorWindow", duration)
197
+ end
198
+
199
+ def newLog()
200
+ settings = GSServerLogSettings.new
201
+ if ServerLogSettings.new(settings, self).exec() == Qt::Dialog.Accepted
202
+ $globals.addServerLogFile(settings)
203
+ end
204
+ end
205
+
206
+ def openLog()
207
+ $windowList.each { |w| w.close unless w == self }
208
+ init
209
+ $globals.currentLogFile = nil
210
+ end
211
+
212
+ def mw_1()
213
+ setMonitorWindow(1)
214
+ end
215
+
216
+ def mw_2()
217
+ setMonitorWindow(2)
218
+ end
219
+
220
+ def mw_5()
221
+ setMonitorWindow(5)
222
+ end
223
+
224
+ def mw_10()
225
+ setMonitorWindow(10)
226
+ end
227
+
228
+ def mw_20()
229
+ setMonitorWindow(20)
230
+ end
231
+
232
+ def mw_30()
233
+ setMonitorWindow(30)
234
+ end
235
+
236
+ def mw_60()
237
+ setMonitorWindow(60)
238
+ end
239
+
240
+ def mw_120()
241
+ setMonitorWindow(120)
242
+ end
243
+
244
+ def showRegularPages()
245
+ $globals.setSetting("ShowRegularPages", @showRegularPages.isOn() ? 1 : 0)
246
+ end
247
+
248
+ def showAuxPages()
249
+ $globals.setSetting("ShowAuxPages", @showAuxPages.isOn() ? 1 : 0)
250
+ end
251
+
252
+ def showSurfers()
253
+ $globals.setSetting("ShowSurfers", @showSurfers.isOn() ? 1 : 0)
254
+ end
255
+
256
+ def showRobots()
257
+ $globals.setSetting("ShowRobots", @showRobots.isOn() ? 1 : 0)
258
+ end
259
+
260
+ def configureClickSpotter()
261
+ Configuration.new(self).exec
262
+ end
263
+
264
+ def about()
265
+ dlg = About.new
266
+ dlg.aboutVersion.text = dlg.aboutVersion.text.gsub(/X\_X\_X/, AppConfig.version)
267
+ dlg.aboutVersion.text = dlg.aboutVersion.text.gsub(/APP\_NAME/, AppConfig.name)
268
+ dlg.caption = dlg.caption.sub(/APP\_NAME/, AppConfig.name)
269
+ dlg.exec
270
+ end
271
+
272
+ def update()
273
+ # Avoid recursive calls in case this function takes a little
274
+ # longer
275
+ @updateTimer.stop()
276
+
277
+ # Delete outdated records
278
+ purgeRecords
279
+
280
+ # Before we process the log file we need to make sure that we have any log
281
+ # file definitions. If not, we open the appropriate configuration dialog.
282
+ newLog if $globals.serverLogFiles.empty?
283
+
284
+ until $globals.logFile
285
+ dlg = LogFileSelector.new(self)
286
+ if dlg.exec == Qt::Dialog.Rejected
287
+ close(true)
288
+ return
289
+ end
290
+ $globals.currentLogFile = dlg.selectedLogFile
291
+ end
292
+ @log.setFileName($globals.logFile)
293
+ setCaption("#{$globals.currentLogFile.name} - #{AppConfig.name} " +
294
+ "#{AppConfig.version}")
295
+
296
+ processLog
297
+ updateWindows
298
+ updateStatusBar
299
+ @updateTimer.start(5000)
300
+ end
301
+
302
+ def processLog
303
+ deadline = Time.now - $globals.getSetting('LogFileDataTimeout') * 60 * 60
304
+
305
+ begin
306
+ while (rec = @log.getNextEntry(deadline)) != nil
307
+ next if rec['url'] == nil
308
+
309
+ # Store hit record
310
+ hr = HitRecord.new(rec)
311
+ $hitRecords.push(hr)
312
+
313
+ # Create or update status code record
314
+ code = rec['code']
315
+ if $statusCodes[code] == nil
316
+ sc = StatusCode.new(code)
317
+ $statusCodes[code] = sc
318
+ else
319
+ sc = $statusCodes[code]
320
+ end
321
+ sc.addHit(hr)
322
+
323
+ # Create or update page record
324
+ url = rec['url']
325
+ if $pages[url] == nil
326
+ p = PageRecord.new(url, rec['isPage'])
327
+ $pages[url] = p
328
+ else
329
+ p = $pages[url]
330
+ end
331
+ p.addHit(hr)
332
+ $recentPages.push(p)
333
+
334
+ # Create or update referer record
335
+ referer = rec['referer']
336
+ if referer
337
+ if $referers[referer] == nil
338
+ r = RefererRecord.new(referer)
339
+ $referers[referer] = r
340
+ else
341
+ r = $referers[referer]
342
+ end
343
+ r.addHit(hr)
344
+ if r.external?
345
+ $recentReferers.push(r)
346
+ else
347
+ # For internal pages we track the number of referrals to
348
+ # other internal pages
349
+ if $pages.has_key?(referer)
350
+ $pages[referer].addReferral(rec['url'])
351
+ end
352
+ end
353
+ end
354
+
355
+ # Create or update visitor record
356
+ key = rec['ip'] + "|" + rec['browser']
357
+ if $visitors[key] == nil
358
+ v = VisitorRecord.new(rec['ip'], rec['browser'])
359
+ $visitors[key] = v
360
+ else
361
+ v = $visitors[key]
362
+ end
363
+ v.addHit(hr)
364
+ v.robot = $globals.isRobot(rec['ip'], rec['browser'], rec['url'])
365
+ $recentVisitors.push(v)
366
+
367
+ end
368
+ rescue SystemCallError
369
+ Qt::MessageBox.warning(self, "Opening log file failed!", "#{$!}",
370
+ Qt::MessageBox.Ok, 0)
371
+ openLog
372
+ end
373
+ end
374
+
375
+ def purgeRecords
376
+ return unless Time.now > @nextPurge
377
+
378
+ deadline = Time.now - $globals.getSetting("LogFileDataTimeout") * 60 * 60
379
+ $visitors.each do |id, v|
380
+ if v.purge(deadline)
381
+ $recentVisitors.delete(v)
382
+ $visitors.delete(id)
383
+ end
384
+ end
385
+
386
+ $referers.each do |url, r|
387
+ if r.purge(deadline)
388
+ $recentReferers.delete(r)
389
+ $referers.delete(url)
390
+ end
391
+ end
392
+
393
+ deletedPages = {}
394
+ $pages.each do |url, p|
395
+ deletedPages[url] = p if p.purge(deadline)
396
+ end
397
+ $pages.each do |url, p|
398
+ p.purgeNextPages(deletedPages.values)
399
+ end
400
+ deletedPages.each_key do |u|
401
+ $recentPages.delete($pages.delete(u))
402
+ end
403
+
404
+ $statusCodes.each do |c, h|
405
+ $statusCodes.delete(c) if h.purge(deadline)
406
+ end
407
+
408
+ $hitRecords.delete_if { |h| h.timeStamp < deadline }
409
+
410
+ @nextPurge = Time.now + PurgeInterval
411
+ end
412
+
413
+ def updateWindows
414
+ $windowList.each do |win|
415
+ win.updateWindow
416
+ end
417
+ end
418
+
419
+ def updateTab(w)
420
+ updateWindow
421
+ end
422
+
423
+ def updateWindow
424
+ funcs = [ method(:updateRecent), method(:updateVisitors),
425
+ method(:updatePages), method(:updateReferers),
426
+ method(:updateCodes) ]
427
+ funcs[@tabWidget.currentPageIndex()].call()
428
+
429
+ @visitorWorldMap.update($visitors) if @visitorWorldMap
430
+ end
431
+
432
+ def updateRecent
433
+
434
+ @hostListCSLV.startUpdate
435
+ deadline = Time.now().localtime() -
436
+ $globals.getSetting("MonitorWindow") * 60
437
+ showSurfers = $globals.getSetting("ShowSurfers") != 0
438
+ showRobots = $globals.getSetting("ShowRobots") != 0
439
+ visitors = {}
440
+ $recentVisitors.each do |v, count|
441
+ if v == nil ||
442
+ (v.robot != nil && !showRobots) ||
443
+ (v.robot == nil && !showSurfers) ||
444
+ v.lastHit.timeStamp < deadline
445
+ next
446
+ end
447
+
448
+ visitors[v.ip] = v
449
+
450
+ if (!@currentGDV.selectedItems.empty? &&
451
+ @currentGDV.selectedItems[v.country] == nil)
452
+ next
453
+ end
454
+ @hostListCSLV.insertItem(v, v.host(), v.hitCount(), v.pageCount(),
455
+ v.lastPage ? v.lastPage.url() : '', v.ip(),
456
+ v.browser())
457
+ end
458
+ @hostListCSLV.finishUpdate
459
+
460
+ @currentGDV.update(visitors)
461
+ @topPageListCSLV.startUpdate
462
+ showRegularPages = $globals.getSetting("ShowRegularPages") != 0
463
+ showAuxPages = $globals.getSetting("ShowAuxPages") != 0
464
+ $recentPages.each do |p, count|
465
+ if p == nil || p.lastHit == nil || p.lastHit.timeStamp < deadline ||
466
+ (p.isPage && !showRegularPages) ||
467
+ (!p.isPage && !showAuxPages)
468
+ next
469
+ end
470
+ @topPageListCSLV.insertItem(p, p.url, count, p.lastHit.bytes * count)
471
+ end
472
+ @topPageListCSLV.finishUpdate
473
+
474
+ @topRefererListCSLV.startUpdate
475
+ $recentReferers.each do |r, count|
476
+ next if r == nil || r.lastHit == nil || r.lastHit.timeStamp < deadline
477
+ @topRefererListCSLV.insertItem(r, r.url, count, r.lastHit.bytes * count)
478
+ end
479
+ @topRefererListCSLV.finishUpdate
480
+ end
481
+
482
+ def updateVisitors
483
+ @visitorGDV.update($visitors)
484
+ @fullHostListCSLV.startUpdate
485
+ showSurfers = $globals.getSetting("ShowSurfers") != 0
486
+ showRobots = $globals.getSetting("ShowRobots") != 0
487
+ $visitors.each_value do |visitor|
488
+ if (!@visitorFilter.text().empty? &&
489
+ !(Regexp.new(@visitorFilter.text()) =~ visitor.host)) ||
490
+ (visitor.robot != nil && !showRobots) ||
491
+ (visitor.robot == nil && !showSurfers) ||
492
+ (!@visitorGDV.selectedItems.empty? &&
493
+ @visitorGDV.selectedItems[visitor.country] == nil)
494
+ next
495
+ end
496
+ @fullHostListCSLV.insertItem(visitor, visitor.host, visitor.hitCount,
497
+ visitor.pageCount, visitor.lastPage ? visitor.lastPage.page.url : '',
498
+ visitor.lastHit.timeStamp, visitor.ip, visitor.browser)
499
+ end
500
+ @fullHostListCSLV.finishUpdate
501
+ end
502
+
503
+ def updatePages
504
+ @pageListCSLV.startUpdate
505
+ showRegularPages = $globals.getSetting("ShowRegularPages") != 0
506
+ showAuxPages = $globals.getSetting("ShowAuxPages") != 0
507
+ $pages.each do |url, page|
508
+ if !@pageFilter.text().empty? &&
509
+ !(Regexp.new(@pageFilter.text()) =~ url) ||
510
+ (page.isPage && !showRegularPages) ||
511
+ (!page.isPage && !showAuxPages)
512
+ next
513
+ end
514
+ @pageListCSLV.insertItem(page, url, page.hitCount, page.entryCount,
515
+ page.exitCount);
516
+ end
517
+ @pageListCSLV.finishUpdate
518
+ end
519
+
520
+ def updateReferers
521
+ @refererListCSLV.startUpdate
522
+ $referers.each do |url, referer|
523
+ if !referer.external? ||
524
+ (!@refererFilter.text().empty? &&
525
+ !(Regexp.new(@refererFilter.text()) =~ url))
526
+ next
527
+ end
528
+ @refererListCSLV.insertItem(referer, url, referer.hitCount)
529
+ end
530
+ @refererListCSLV.finishUpdate
531
+ end
532
+
533
+ def updateCodes
534
+ @statusCodeListCSLV.startUpdate
535
+ $statusCodes.each do |code, rec|
536
+ @statusCodeListCSLV.insertItem(code, code, rec.description,
537
+ rec.hitCount, 0)
538
+ end
539
+ @statusCodeListCSLV.finishUpdate
540
+
541
+ @hitListCSLV.startUpdate
542
+ $hitRecords.each do |hit|
543
+ next if @statusCodeListCSLV.selectedItems[hit.code] == nil
544
+ @hitListCSLV.insertItem(hit, hit.timeStamp, hit.code,
545
+ hit.visitor.host, hit.request,
546
+ hit.referer ? hit.referer.url : '')
547
+ end
548
+ @hitListCSLV.finishUpdate
549
+ end
550
+
551
+ def updateStatusBar
552
+ now = Time.now()
553
+ i = $hitRecords.length() - 1
554
+ pages = 0
555
+ bytes = 0
556
+ while (i > 0) and ($hitRecords[i].timeStamp > Time.now().localtime() - 60)
557
+ i -= 1
558
+ bytes += $hitRecords[i].bytes
559
+ pages += 1 if $hitRecords[i].page.isPage
560
+ end
561
+ statusBar().message("Hits: #{$hitRecords.length() - 1 - i}/min " +
562
+ "Pages: #{pages}/min " +
563
+ "Traffic: #{bytes / 60} kBytes/s " +
564
+ "Queues (D/G/T): #{$resolver.queueSize}/" +
565
+ "#{$geoLocator.queueSize}/" +
566
+ "#{$traceRouter.queueSize}")
567
+ end
568
+
569
+ def clearVisitorFilter()
570
+ @visitorFilter.setText("")
571
+ updateVisitors
572
+ end
573
+
574
+ def clearPageFilter()
575
+ @pageFilter.setText("")
576
+ updatePages
577
+ end
578
+
579
+ def clearRefererFilter()
580
+ @refererFilter.setText("")
581
+ updateReferers
582
+ end
583
+
584
+ def recentHostClicked(item)
585
+ return if item == nil
586
+ visitor = $visitors[item.text(4) + "|" + item.text(5)]
587
+ VisitorInformation.new(visitor)
588
+ end
589
+
590
+ def topPageClicked(item)
591
+ return if item == nil
592
+ PageInformation.new($pages[item.text(0)])
593
+ end
594
+
595
+ def topRefererClicked(item)
596
+ return if item == nil
597
+ RefererInformation.new($referers[item.text(0)])
598
+ end
599
+
600
+ def hostClicked(item)
601
+ return if item == nil
602
+ visitor = $visitors[item.text(5) + "|" + item.text(6)]
603
+ VisitorInformation.new(visitor)
604
+ end
605
+
606
+ def largeVisitorMapBtnClicked
607
+ @visitorWorldMap.close(true) if @visitorWorldMap
608
+
609
+ @visitorWorldMap = WorldMap.new(self)
610
+ end
611
+
612
+ def worldMapClosed
613
+ @visitorWorldMap = nil
614
+ end
615
+
616
+ def pageClicked(item)
617
+ return if item == nil
618
+ PageInformation.new($pages[item.text(0)])
619
+ end
620
+
621
+ def refererClicked(item)
622
+ return if item == nil
623
+ RefererInformation.new($referers[item.text(0)])
624
+ end
625
+
626
+ end
627
+