spy-vs-spy 0.0.1 → 0.0.3

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.
Files changed (64) hide show
  1. data/lib/spy-vs-spy.rb +473 -7
  2. data/spy-vs-spy.gemspec +69 -10
  3. data/test/firefox/firefox-3.1b2.txt +9 -0
  4. data/test/firefox/firefox-3.1b2pre.txt +4 -0
  5. data/test/firefox/firefox-3.1b3.txt +32 -0
  6. data/test/firefox/firefox-3.1b3pre.txt +2 -0
  7. data/test/firefox/firefox-3.5.1.txt +41 -0
  8. data/test/firefox/firefox-3.5.12.txt +1 -0
  9. data/test/firefox/firefox-3.5.2.txt +27 -0
  10. data/test/firefox/firefox-3.5.3.txt +22 -0
  11. data/test/firefox/firefox-3.5.3pre.txt +1 -0
  12. data/test/firefox/firefox-3.5.4.txt +3 -0
  13. data/test/firefox/firefox-3.5.5.txt +3 -0
  14. data/test/firefox/firefox-3.5.txt +40 -0
  15. data/test/firefox/firefox-3.5b4.txt +9 -0
  16. data/test/firefox/firefox-3.5b4pre.txt +3 -0
  17. data/test/firefox/firefox-3.6.txt +2 -0
  18. data/test/firefox/firefox-3.6a1pre.txt +6 -0
  19. data/test/firefox/firefox-3.6b1.txt +1 -0
  20. data/test/firefox/firefox-3.8.txt +3 -0
  21. data/test/msie/msie-5.5.txt +177 -0
  22. data/test/msie/msie-5.5b1.txt +1 -0
  23. data/test/msie/msie-6,0.txt +1 -0
  24. data/test/msie/msie-6.0.1.txt +1 -0
  25. data/test/msie/msie-6.0.txt +1817 -0
  26. data/test/msie/msie-6.0b.txt +14 -0
  27. data/test/msie/msie-6.1.txt +2 -0
  28. data/test/msie/msie-7.0.txt +1208 -0
  29. data/test/msie/msie-7.0b.txt +12 -0
  30. data/test/msie/msie-8.0.txt +340 -0
  31. data/test/safari/safari-1.0.3.txt +10 -0
  32. data/test/safari/safari-1.0.txt +8 -0
  33. data/test/safari/safari-1.2.2.txt +9 -0
  34. data/test/safari/safari-1.2.3.txt +10 -0
  35. data/test/safari/safari-1.2.4.txt +21 -0
  36. data/test/safari/safari-1.2.txt +5 -0
  37. data/test/safari/safari-1.3.1.txt +24 -0
  38. data/test/safari/safari-1.3.2.txt +14 -0
  39. data/test/safari/safari-1.3.txt +13 -0
  40. data/test/safari/safari-2.0.1.txt +9 -0
  41. data/test/safari/safari-2.0.2.txt +25 -0
  42. data/test/safari/safari-2.0.3.txt +37 -0
  43. data/test/safari/safari-2.0.4.txt +44 -0
  44. data/test/safari/safari-2.0.txt +21 -0
  45. data/test/safari/safari-3.0.1.txt +8 -0
  46. data/test/safari/safari-3.0.2.txt +14 -0
  47. data/test/safari/safari-3.0.3.txt +20 -0
  48. data/test/safari/safari-3.0.4.txt +37 -0
  49. data/test/safari/safari-3.0.txt +53 -0
  50. data/test/safari/safari-3.1.1.txt +77 -0
  51. data/test/safari/safari-3.1.2.txt +48 -0
  52. data/test/safari/safari-3.1.txt +22 -0
  53. data/test/safari/safari-3.2.1.txt +37 -0
  54. data/test/safari/safari-3.2.2.txt +9 -0
  55. data/test/safari/safari-3.2.3.txt +2 -0
  56. data/test/safari/safari-3.2.txt +7 -0
  57. data/test/safari/safari-4.0.1.txt +2 -0
  58. data/test/safari/safari-4.0.2.txt +12 -0
  59. data/test/safari/safari-4.0.3.txt +5 -0
  60. data/test/safari/safari-4.0.txt +66 -0
  61. data/test/safari/safari-4.0dp1.txt +8 -0
  62. data/test/safari/safari.txt +31 -0
  63. data/test/ss-test.rb +143 -3
  64. metadata +62 -2
data/lib/spy-vs-spy.rb CHANGED
@@ -21,7 +21,16 @@
21
21
  see LICENSE file for details
22
22
 
23
23
  =end
24
+ class String
25
+ def starts_with?(str)
26
+ str = str.to_str
27
+ head = self[0, str.length]
28
+ head == str
29
+ end
30
+ end
31
+
24
32
  module SoldierOfCode
33
+
25
34
  class SpyVsSpy
26
35
 
27
36
  def initialize(app)
@@ -38,14 +47,429 @@ module SoldierOfCode
38
47
  end
39
48
 
40
49
  def deconstruct(agent)
41
- ParseUserAgent.new(agent)
50
+ ParseUserAgent.new.parse(agent)
42
51
  end
43
52
 
44
53
  end
45
54
 
46
55
  class ParseUserAgent
47
56
 
48
- attr_reader :ostype, :browser, :os_version, :browser_version_major
57
+ @@safari = {
58
+ "1.0" => ["85.5", "85.6", "85.7"],
59
+ "1,0.3" => ["85.8.1", "85.8", "85"],
60
+ "1.2" => ["125", "125.1"],
61
+ "1.2.2" => ["85.8", "125.7", "125.8"],
62
+ "1.2.3" => ["100", "125.9"],
63
+ "1.2.4" => ["125", "125.11", "125.12", "125.12_Adobe", "125.5.5"],
64
+ "1.3" => ["312"],
65
+ "1.3.1" => ["312.3.3", "312.3.1", "312.3"],
66
+ "1.3.2" => ["312.5", "312.6", "312.5_Adobe"],
67
+ "2.0" => ["412", "412.2.2", "412.2_Adobe"],
68
+ "2.0.1" => ["412.5", "412.6", "412.5_Adobe"],
69
+ "2.0.2" => ["416.13", "416.12", "312", "416.13_Adobe", "416.12_Adobe"],
70
+ "2.0.3" => ["417.9.3", "417.8_Adobe", "417.9.2", "417.8", "412.2"],
71
+ "2.0.4" => ["419.3"],
72
+ "3.0" => ["523.13", "522.11.3", "523.12.9", "523.6.1", "522.11.1", "522.11", "522.8.3", "522.7"],
73
+ "3.0.1" => ["522.12.2"],
74
+ "3.0.2" => ["522.13.1", "522.12"],
75
+ "3.0.3" => ["522.15.5", "523.6", "522.12.1"],
76
+ "3.0.4" => ["523.11", "523.12.2", "523.10", "523.10.6", "523.15", "523.12"],
77
+ "3.1.1" => ["525.17", "525.18", "525.20"],
78
+ "3.2.1" => ["525.27.1"]
79
+ }
80
+
81
+ attr_reader :ostype, :browser, :os_version, :browser_version_major, :browser_version_minor, :browser_version_sub, :mobile_browser, :console_browser
82
+
83
+ #
84
+ #
85
+ # =======================================
86
+ # description:
87
+ # ----------------
88
+ #
89
+ # params:
90
+ # ----------------
91
+ #
92
+ # returns:
93
+ # ----------------
94
+ def parse(agent)
95
+
96
+ pass1 = Regexp.new("^([^\\(]*)?[ ]*?(\\([^\\)]*\\))?[ ]*([^\\(]*)?[ ]*?(\\([^\\)]*\\))?[ ]*(.*)")
97
+ pass1.match(agent)
98
+
99
+ @product_token = $1 || ''
100
+ @detail = $2 || ''
101
+ @engine = $3 || ''
102
+ @renderer = $4 || ''
103
+ @identifier = $5 || ''
104
+
105
+ #puts "#{__FILE__}:#{__LINE__} #{__method__} [#{@product_token}] [#{@detail}] [#{@engine}] [#{@renderer}] [#{@identifier}]"
106
+
107
+ @platform = identify_platform(agent)
108
+ @mobile = is_mobile?(agent)
109
+ @ostype = identify_os
110
+
111
+ matched = process_safari(agent)
112
+ matched = process_firefox(agent) unless matched
113
+ matched = process_ie(agent) unless matched
114
+ matched = process_opera(agent) unless matched
115
+ matched = process_netscape(agent) unless matched
116
+
117
+ self
118
+ end
119
+
120
+ #
121
+ #
122
+ # =======================================
123
+ # description:
124
+ # ----------------
125
+ #
126
+ # params:
127
+ # ----------------
128
+ #
129
+ # returns:
130
+ # ----------------
131
+ def identify_platform(agent)
132
+ platform = "Desktop"
133
+ ["PLAYSTATION 3", "wii", "PlayStation Portable", "Xbox", "iPhone", "iPod", "BlackBerry", "Android", "HTC-", "LG", "Motorola", "Nokia", "Treo", "Pre/", "Samsung", "SonyEricsson"].each do |agt|
134
+ platform = agt if @platform=="Desktop" && agent.include?(agt)
135
+ end
136
+ platform
137
+ end
138
+
139
+ #
140
+ #
141
+ # =======================================
142
+ # description:
143
+ # ----------------
144
+ #
145
+ # params:
146
+ # ----------------
147
+ #
148
+ # returns:
149
+ # ----------------
150
+ def is_mobile?(agent)
151
+ ["iPhone", "iPod", "BlackBerry", "Android", "HTC-", "LG", "Motorola", "Nokia", "Treo", "Pre/", "Samsung", "SonyEricsson"].each do |mobile_agt|
152
+ return true if agent.include?(mobile_agt)
153
+ end
154
+ end
155
+
156
+ #
157
+ #
158
+ # =======================================
159
+ # description:
160
+ # ----------------
161
+ #
162
+ # params:
163
+ # ----------------
164
+ #
165
+ # returns:
166
+ # ----------------
167
+ def identify_os
168
+ os_list = ["Mac OS X", "Linux", "Windows"]
169
+ os = nil
170
+ os_list.each do |o|
171
+ os = o if @detail.include?(o)
172
+ end
173
+ os
174
+ end
175
+
176
+ #
177
+ #
178
+ # =======================================
179
+ # description:
180
+ # ----------------
181
+ #
182
+ # params:
183
+ # ----------------
184
+ #
185
+ # returns:
186
+ # ----------------
187
+ def process_safari(agent_string)
188
+ @identifier = @engine if @identifier == ""
189
+
190
+ if agent_string.include?("Safari")
191
+ @browser = "Safari"
192
+ end
193
+
194
+ if @identifier.include?("Safari") || @renderer.include?("Safari") || @detail.include?("iPhone") || @identifier.include?("iPhone")
195
+ @browser = "Safari"
196
+
197
+ identifier_sub = nil
198
+ @identifier.gsub(/[\\:\?'"%!@#\$\^&\*\(\)\+]/, '').split(" ").each do |ident|
199
+ identifier_sub = ident.sub("Safari\/", "") if ident.include?("Safari")
200
+ identifier_sub.gsub!(/[\+]/, '') if identifier_sub && identifier_sub.include?("+")
201
+ end
202
+ if identifier_sub == nil && @renderer.include?("Safari")
203
+ renderer_gsub_gsub = @renderer.sub("\(", "").sub("\)", "")
204
+ renderer_gsub_gsub.strip.split(",").each do |sec|
205
+ identifier_sub = sec.sub("Safari\/", "").strip if sec.include?("Safari")
206
+ end
207
+ end
208
+
209
+ @@safari.each do |k, v|
210
+ version_numbers = k.gsub(",", ".").split(".")
211
+ v.each do |num|
212
+ if identifier_sub == num
213
+ @browser_version_major = version_numbers[0] if version_numbers.size > 0
214
+ @browser_version_minor = version_numbers[1] if version_numbers.size > 1
215
+ @browser_version_sub = version_numbers[2] if version_numbers.size > 2
216
+ end
217
+ break if @browser_version_major
218
+ end
219
+ # Special case 58.8 - check WebKit numbers
220
+ # Special case 312 - check AppleWebKit
221
+ # Special case 419.3 - could me mobile v3 check AppleWebKit for 420+
222
+
223
+ if identifier_sub == "312" then
224
+ engine_sub = @engine.sub("AppleWebKit/", "")
225
+ if engine_sub.include? "416.11" then
226
+ @browser_version_major = '2'
227
+ @browser_version_minor = '0'
228
+ @browser_version_sub = '2'
229
+ else
230
+ end
231
+ end
232
+
233
+ if identifier_sub == "419.3" then
234
+ engine_sub = @engine.sub("AppleWebKit/", "")
235
+ if engine_sub.include?("420") then
236
+ @browser_version_major = '3'
237
+ @browser_version_minor = '0'
238
+ @browser_version_sub = nil
239
+ else
240
+ end
241
+ end
242
+
243
+ if (identifier_sub == "Safari") || (@identifier == "Safari/")then
244
+ engine_sub = @engine.sub("AppleWebKit/", "")
245
+ if engine_sub.include?("418.9") || engine_sub.include?("418.8") then
246
+ @browser_version_major = '2'
247
+ @browser_version_minor = '0'
248
+ @browser_version_sub = '4'
249
+ else
250
+ end
251
+ end
252
+
253
+ ident_sub = nil
254
+ if @identifier.include?("Version") then
255
+ @identifier.split(" ").each do |ident|
256
+ ident_sub = ident.sub("Version\/", "") if ident.include?("Version")
257
+ if ident_sub then
258
+ vs = ident_sub.gsub(",", ".").split(".")
259
+ @browser_version_major = vs[0] if vs.size > 0
260
+ @browser_version_minor = vs[1] if vs.size > 1
261
+ @browser_version_sub = vs[2] if vs.size > 2
262
+ end
263
+ end
264
+ end
265
+
266
+ if @identifier == "Safari/412 Privoxy/3.0" then
267
+ @browser_version_major = '2'
268
+ @browser_version_minor = '0'
269
+ @browser_version_sub = nil
270
+ end
271
+
272
+ break if @browser_version_major
273
+ end
274
+ end
275
+
276
+ if @browser == nil && agent_string.include?("Mac OS X") && agent_string.include?("AppleWebKit")
277
+ @browser = "Safari"
278
+ end
279
+
280
+ return true if @browser && @browser_version_major
281
+ false
282
+ end
283
+
284
+ #
285
+ #
286
+ # =======================================
287
+ # description:
288
+ # ----------------
289
+ #
290
+ # params:
291
+ # ----------------
292
+ #
293
+ # returns:
294
+ # ----------------
295
+ def process_ie(agent)
296
+ # @detail
297
+ if agent.include?("MSIE")
298
+ @browser = "MSIE"
299
+ end
300
+ if @detail.include?("MSIE")
301
+ @detail.gsub(/[\\:\?'"%!@#\$\^&\*\(\)\+]/, '').split(";").each do |sec|
302
+ if sec.strip.starts_with?("MSIE ") then
303
+ s = sec.strip.sub("MSIE ", "").sub("06", "0.6").sub(",", ".").split(".")
304
+ @browser_version_major = s[0] if s.size > 0
305
+ @browser_version_minor = s[1] if s.size > 1
306
+ end
307
+
308
+ break if @browser_version_major
309
+ end
310
+ end
311
+
312
+ unless @browser_version_major
313
+ if agent.include?("MSIE 6.0")
314
+ @browser = "MSIE"
315
+ @browser_version_major = '6'
316
+ @browser_version_minor = '0'
317
+ end
318
+ if agent.include?("MSIE 7.0")
319
+ @browser = "MSIE"
320
+ @browser_version_major = '7'
321
+ @browser_version_minor = '0'
322
+ end
323
+ if agent.include?("MSIE 8.0")
324
+ @browser = "MSIE"
325
+ @browser_version_major = '8'
326
+ @browser_version_minor = '0'
327
+ end
328
+ end
329
+ end
330
+
331
+ #
332
+ #
333
+ # =======================================
334
+ # description:
335
+ # ----------------
336
+ #
337
+ # params:
338
+ # ----------------
339
+ #
340
+ # returns:
341
+ # ----------------
342
+ def process_firefox(agent)
343
+ @identifier = @engine if @identifier == ""
344
+
345
+ if agent.include?("Firefox")
346
+ @browser = "Firefox"
347
+ end
348
+
349
+ if @identifier.include?("Firefox") || @renderer.include?("Firefox") || @engine.include?("Firefox")
350
+ @browser = "Firefox"
351
+
352
+
353
+ identifier_sub = nil
354
+ @identifier.gsub(/[\\:\?'"%!@#\$\^&\*\(\)\+]/, '').split(" ").each do |ident|
355
+ identifier_sub = ident.sub("Firefox\/", "").sub("Gecko/", "") if ident.include?("Firefox")
356
+ identifier_sub.gsub!(/[\+]/, '') if identifier_sub && identifier_sub.include?("+")
357
+ end
358
+ if identifier_sub == nil && @renderer.include?("Firefox")
359
+ renderer_gsub_gsub = @renderer.sub("\(", "").sub("\)", "")
360
+ renderer_gsub_gsub.strip.split(",").each do |sec|
361
+ identifier_sub = sec.sub("Firefox\/", "").strip if sec.include?("Firefox")
362
+ end
363
+ end
364
+ if identifier_sub == nil && @engine.include?("Firefox")
365
+ @engine.gsub(/[\\:\?'"%!@#\$\^&\*\(\)\+]/, '').split(" ").each do |ident|
366
+ identifier_sub = ident.sub("Firefox\/", "").sub("Gecko/", "") if ident.include?("Firefox")
367
+ identifier_sub.gsub!(/[\+]/, '') if identifier_sub && identifier_sub.include?("+")
368
+ end
369
+ end
370
+
371
+ if identifier_sub
372
+ version_numbers = identifier_sub.split(".")
373
+ @browser_version_major = version_numbers[0] if version_numbers.size > 0
374
+ @browser_version_minor = version_numbers[1] if version_numbers.size > 1
375
+ @browser_version_sub = version_numbers[2] if version_numbers.size > 2
376
+ end
377
+
378
+ end
379
+ return true if @browser && @browser_version_major
380
+ false
381
+ end
382
+
383
+ #
384
+ #
385
+ # =======================================
386
+ # description:
387
+ # ----------------
388
+ #
389
+ # params:
390
+ # ----------------
391
+ #
392
+ # returns:
393
+ # ----------------
394
+ def process_opera(agent)
395
+
396
+ end
397
+
398
+ #
399
+ #
400
+ # =======================================
401
+ # description:
402
+ # ----------------
403
+ #
404
+ # params:
405
+ # ----------------
406
+ #
407
+ # returns:
408
+ # ----------------
409
+ def process_netscape(agent)
410
+
411
+ end
412
+
413
+ =begin
414
+
415
+ def known_browser(browser)
416
+
417
+ browsers = %w[ Firefox Safari MSIE ]
418
+ flag = false
419
+ browsers.each do |b|
420
+ flag = true if b == browser
421
+ end
422
+
423
+ flag
424
+ end
425
+
426
+ def known_safari_agent_string(string)
427
+ agents = []
428
+ agents << "AppleWebKit"
429
+ agents << "iPhone"
430
+
431
+ agents.each do |agent|
432
+ return true if string.include?(agent)
433
+ end
434
+ false
435
+ end
436
+
437
+ def mobile_browser?(string)
438
+ agents = []
439
+ agents << "iPhone"
440
+
441
+ agents.each do |agent|
442
+ if string.include?(agent)
443
+ @mobile_browser = agent
444
+ return true
445
+ end
446
+ end
447
+ false
448
+ end
449
+
450
+ def console_browser?(string)
451
+ agents = []
452
+
453
+ agents.each do |agent|
454
+ if string.include?(agent)
455
+ @console_browser = agent
456
+ return true
457
+ end
458
+ end
459
+ false
460
+ end
461
+
462
+ def is_safari?(str)
463
+ s = []
464
+ s << "iPhone"
465
+ s << "Safari"
466
+
467
+ flag = false
468
+ s.each do |st|
469
+ flag = true if str.include?(st)
470
+ end
471
+ flag
472
+ end
49
473
 
50
474
  def parse(user_agent)
51
475
  if '-' == user_agent
@@ -69,24 +493,66 @@ module SoldierOfCode
69
493
  # cycle through the agents to set browser and version (MSIE is set later)
70
494
  if @agents && @agents.length > 0
71
495
  @agents.each {|agent|
496
+
72
497
  parts = agent.split('/')
73
498
  @browser = parts[0]
74
499
  @browser_version = parts[1]
500
+
75
501
  if @browser == 'Firefox'
76
502
  @browser_version_major = parts[1].slice(0, 3)
77
503
  @browser_version_minor = parts[1].sub(@browser_version_major, '').sub('.', '')
504
+
78
505
  elsif @browser == 'Safari'
79
- if parts[1].slice(0, 3).to_f < 400
80
- @browser_version_major = '1'
81
- else
82
- @browser_version_major = '2'
506
+ rx = Regexp.new("Version/([0-9]+)\.([0-9]+)\.([0-9]+)")
507
+ rx.match(user_agent)
508
+
509
+ @browser_version_major = $1
510
+ @browser_version_minor = $2
511
+ @browser_version_sub = $3
512
+
513
+ unless $1
514
+
515
+ v1_0_3 = []
516
+ v1_0_3 << "85.8.1"
517
+ v1_0_3 << "85"
518
+ v1_0_3 << "85.8"
519
+
520
+
521
+ vs = parts[1].split("\.")
522
+ vs1 = vs[0].to_i
523
+ if vs1 < 126
524
+ @browser_version_major = '1'
525
+
526
+ if vs[1].to_i < 8
527
+ @browser_version_minor = '0'
528
+ @browser_version_sub = '0'
529
+ elsif vs[1].to_i >= 8
530
+ @browser_version_minor = '0'
531
+ @browser_version_sub = '3'
532
+ end
533
+
534
+ end
535
+
83
536
  end
537
+
84
538
  else
539
+ # puts "#{__FILE__}:#{__LINE__} #{__method__} here---"
85
540
  @browser_version_major = parts[1].slice(0, 1)
86
541
  end
87
542
  }
88
543
  end
89
544
 
545
+
546
+ if !known_browser(@browser) then
547
+
548
+ @browser = 'Safari' if is_safari?(user_agent) || known_safari_agent_string(user_agent)
549
+
550
+ end
551
+
552
+ # I'm thinking of making this a lazy call....
553
+ mobile_browser?(user_agent)
554
+ console_browser?(user_agent)
555
+
90
556
  # grab all of the properties (within parens)
91
557
  # should be in relation to the agent if possible
92
558
  @detail = @user_agent
@@ -135,6 +601,6 @@ module SoldierOfCode
135
601
  self
136
602
  end
137
603
 
138
-
604
+ =end
139
605
  end
140
606
  end
data/spy-vs-spy.gemspec CHANGED
@@ -1,17 +1,76 @@
1
1
  Gem::Specification.new do |s|
2
- s.name = "spy-vs-spy"
3
- s.version = "0.0.1"
4
- s.date = "2009-11-19"
5
- s.summary = "UserAgent Detection Middleware for Rack."
6
- s.email = "kaptiankrispy@soldierofcode.com"
2
+ s.name = "spy-vs-spy"
3
+ s.version = "0.0.3"
4
+ s.date = "2009-11-23"
5
+ s.summary = "UserAgent Detection Middleware for Rack."
6
+ s.email = "kaptiankrispy@soldierofcode.com"
7
7
  s.homepage = "http://github.com/kuccello/Spy-Vs-Spy"
8
8
  s.description = ""
9
9
  s.has_rdoc = true
10
- s.authors = ["Kristan 'Krispy' Uccello"]
11
- s.files = ["README",
12
- "spy-vs-spy.gemspec",
13
- "lib/spy-vs-spy.rb"]
14
- s.test_files = ["test/ss-test.rb"]
10
+ s.authors = ["Kristan 'Krispy' Uccello"]
11
+ s.files = ["README",
12
+ "spy-vs-spy.gemspec",
13
+ "lib/spy-vs-spy.rb"]
14
+ s.test_files = ["test/ss-test.rb", "test/msie/msie-5.5.txt",
15
+ "test/msie/msie-5.5b1.txt",
16
+ "test/msie/msie-6,0.txt",
17
+ "test/msie/msie-6.0.1.txt",
18
+ "test/msie/msie-6.0.txt",
19
+ "test/msie/msie-6.0b.txt",
20
+ "test/msie/msie-6.1.txt",
21
+ "test/msie/msie-7.0.txt",
22
+ "test/msie/msie-7.0b.txt",
23
+ "test/msie/msie-8.0.txt",
24
+ "test/safari/safari-1.0.3.txt",
25
+ "test/safari/safari-1.2.3.txt",
26
+ "test/safari/safari-1.3.1.txt",
27
+ "test/safari/safari-2.0.1.txt",
28
+ "test/safari/safari-2.0.4.txt",
29
+ "test/safari/safari-3.0.2.txt",
30
+ "test/safari/safari-3.0.txt",
31
+ "test/safari/safari-3.1.txt",
32
+ "test/safari/safari-3.2.3.txt",
33
+ "test/safari/safari-4.0.2.txt",
34
+ "test/safari/safari-4.0dp1.txt",
35
+ "test/safari/safari-1.0.txt",
36
+ "test/safari/safari-1.2.4.txt",
37
+ "test/safari/safari-1.3.2.txt",
38
+ "test/safari/safari-2.0.2.txt",
39
+ "test/safari/safari-2.0.txt",
40
+ "test/safari/safari-3.0.3.txt",
41
+ "test/safari/safari-3.1.1.txt",
42
+ "test/safari/safari-3.2.1.txt",
43
+ "test/safari/safari-3.2.txt",
44
+ "test/safari/safari-4.0.3.txt",
45
+ "test/safari/safari.txt",
46
+ "test/safari/safari-1.2.2.txt",
47
+ "test/safari/safari-1.2.txt",
48
+ "test/safari/safari-1.3.txt",
49
+ "test/safari/safari-2.0.3.txt",
50
+ "test/safari/safari-3.0.1.txt",
51
+ "test/safari/safari-3.0.4.txt",
52
+ "test/safari/safari-3.1.2.txt",
53
+ "test/safari/safari-3.2.2.txt",
54
+ "test/safari/safari-4.0.1.txt",
55
+ "test/safari/safari-4.0.txt",
56
+ "test/firefox/firefox-3.1b2.txt",
57
+ "test/firefox/firefox-3.1b3.txt",
58
+ "test/firefox/firefox-3.5.1.txt",
59
+ "test/firefox/firefox-3.5.2.txt",
60
+ "test/firefox/firefox-3.5.3pre.txt",
61
+ "test/firefox/firefox-3.5.5.txt",
62
+ "test/firefox/firefox-3.5b4.txt",
63
+ "test/firefox/firefox-3.6.txt",
64
+ "test/firefox/firefox-3.6b1.txt",
65
+ "test/firefox/firefox-3.1b2pre.txt",
66
+ "test/firefox/firefox-3.1b3pre.txt",
67
+ "test/firefox/firefox-3.5.12.txt",
68
+ "test/firefox/firefox-3.5.3.txt",
69
+ "test/firefox/firefox-3.5.4.txt",
70
+ "test/firefox/firefox-3.5.txt",
71
+ "test/firefox/firefox-3.5b4pre.txt",
72
+ "test/firefox/firefox-3.6a1pre.txt",
73
+ "test/firefox/firefox-3.8.txt"]
15
74
  s.rdoc_options = ["--main", "README"]
16
75
  s.extra_rdoc_files = ["README"]
17
76
  end
@@ -0,0 +1,9 @@
1
+ Mozilla/5.0 (X11; U; DragonFly i386; de; rv:1.9.1b2) Gecko/20081201 Firefox/3.1b2
2
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; de-AT; rv:1.9.1b2) Gecko/20081201 Firefox/3.1b2
3
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; sv-SE; rv:1.9.1b2) Gecko/20081201 Firefox/3.1b2
4
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; it; rv:1.9.1b2) Gecko/20081201 Firefox/3.1b2
5
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1b2) Gecko/20081201 Firefox/3.1b2
6
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; de-AT; rv:1.9.1b2) Gecko/20081201 Firefox/3.1b2
7
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.1b2) Gecko/20081201 Firefox/3.1b2
8
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.9.1b2) Gecko/20081201 Firefox/3.1b2
9
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; ko; rv:1.9.1b2) Gecko/20081201 Firefox/3.1b2
@@ -0,0 +1,4 @@
1
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; x64; en-US; rv:1.9.1b2pre) Gecko/20081026 Firefox/3.1b2pre
2
+ Mozilla/5.0 (Windows; U; Windows NT 6.0 x64; en-US; rv:1.9.1b2pre) Gecko/20081026 Firefox/3.1b2pre
3
+ Mozilla/5.0 (Windows; U; Windows NT 6.0 ; x64; en-US; rv:1.9.1b2pre) Gecko/20081026 Firefox/3.1b2pre
4
+ Mozilla/5.0 (Windows; U; Windows NT 5.1 ; x64; en-US; rv:1.9.1b2pre) Gecko/20081026 Firefox/3.1b2pre
@@ -0,0 +1,32 @@
1
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1b3) Gecko/20090327 Fedora/3.1-0.11.beta3.fc11 Firefox/3.1b3
2
+ Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1b3) Gecko/20090312 Firefox/3.1b3
3
+ Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1b3) Gecko/20090407 Firefox/3.1b3
4
+ Mozilla/5.0 (X11; U; Linux i686 (x86_64); en-US; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
5
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; pl; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3 GTB5 (.NET CLR 3.5.30729)
6
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
7
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.1b3;MEGAUPLOAD 1.0 (.NET CLR 3.5.30729)
8
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3 GTB5 (.NET CLR 3.5.30729)
9
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; en-GB; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3 (.NET CLR 3.5.30729)
10
+ Mozilla/5.0 (Windows; U; Windows NT 6.1; de; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
11
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; fr; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
12
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; es-AR; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
13
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1b3) Gecko/20090405 Firefox/3.1b3
14
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3 (.NET CLR 3.5.30729)
15
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; en-GB; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
16
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3 (.NET CLR 3.5.30729)
17
+ Mozilla/5.0 (Windows; U; Windows NT 6.0; de; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
18
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; ru; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
19
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; nl; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3 (.NET CLR 3.5.30729)
20
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3 (.NET CLR 3.5.30729)
21
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
22
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3 GTB5 (.NET CLR 3.5.30729)
23
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3 (.NET CLR 3.5.30729)
24
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3 (.NET CLR 3.5.21022)
25
+ Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3 (.NET CLR 3.5.30729)
26
+ Mozilla/5.0 (Macintosh; U; PPC Mac OS X 10.5; en-US; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
27
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
28
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; fr; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
29
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; es-ES; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
30
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3 GTB5
31
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-GB; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
32
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.4; sv-SE; rv:1.9.1b3) Gecko/20090305 Firefox/3.1b3
@@ -0,0 +1,2 @@
1
+ Mozilla/5.0 (Windows; U; Windows NT 5.2; en-US; rv:1.9.1b3pre) Gecko/20090105 Firefox/3.1b3pre
2
+ Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20090204 Firefox/3.1b3pre