handset_detection 0.1.1 → 0.1.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 171d53310321c9a9aa5173e52adafaf3e50a222e
4
- data.tar.gz: 0d30b245f08d3b079dbfc0d3b6f4404a24029283
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ N2YxM2E1MjA2ODNmOTVkODM2ODVkMTY5M2NhNWEzZjUzMTc2ZmM3Mg==
5
+ data.tar.gz: !binary |-
6
+ NjNkYTM1ZDAzOGM0NzkwZTcwNTVhMzFmZjBlNDlhYjY4MGU2YmY0ZQ==
5
7
  SHA512:
6
- metadata.gz: a88fde905056abb3cb011b6e723caa741276133c283a19f9b4c3b79bb35932d4c76b747cd08152de29e17ca9e97776a0b314179a1a0e6d1cb8cd8a375132a385
7
- data.tar.gz: e2f4e48c3cb022b17f8f939d6f4d61e5dcbdade57b8e44c553c115b2f17e08f8927b756caa02f23b8af3ebf9885bc60f698dbc8fcddf0debbb3fe7bb60c63e68
8
+ metadata.gz: !binary |-
9
+ MjFlZWIwNGRkM2NiOTkwZmYxNGYxM2YxZTlmNDU4ZjZhMWNlZTY0YmMwM2Rj
10
+ MzgzOWM0MDYxNTkyNjE4OWIxYzg3MzUxMTFhYjM2NTcxOWRhNjc2ZGQyZmI1
11
+ MGQ2ZTEzNTRiZjFhMjFmYWQ2Y2Q5Yzk4NDE5ZmQ4YmJlODE4YjQ=
12
+ data.tar.gz: !binary |-
13
+ YWI1ZTkwYmQyNWIwNmE5NmZlMjhlOWU4MjQwNjg5MmJkYjhiMzA4MTc5ODg2
14
+ OGY3NTBmMzhjYTAwNGMzZDI5NDcxYTljZDBhMjkzZTI5OGQzNzY4NzUwYzE0
15
+ MjZjODA3MWQ3MDZjODJmY2VhOTQ2NTU0YTA4ZTJjYzQ4N2RmNzI=
@@ -27,7 +27,6 @@
27
27
  require 'active_support/core_ext/object/blank'
28
28
  require 'json'
29
29
  require 'digest/md5'
30
- require 'socket'
31
30
  require 'tcp_timeout'
32
31
  require 'uri'
33
32
 
@@ -36,9 +35,9 @@ DETECTIONV4_GENERIC = 1
36
35
 
37
36
  class Base
38
37
  def initialize
39
- @config = {}
38
+ @config = {}
40
39
  @api_base = '/apiv4/'
41
- @detected_rule_key = {}
40
+ @detected_rule_key = {}
42
41
  @device_ua_filter = /[ _\\#\-,.\/:"']/
43
42
  @extra_ua_filter = /[ ]/
44
43
  @apikit = 'Ruby 4.0.0'
@@ -46,42 +45,46 @@ class Base
46
45
  @logger_port = 80
47
46
  @reply = {}
48
47
  @tree = {}
49
- @detection_config = {
48
+ @detection_config = {
50
49
  'device-ua-order' => ['x-operamini-phone-ua', 'x-mobile-ua', 'device-stock-ua', 'user-agent', 'agent'],
51
50
  'platform-ua-order' => ['x-operamini-phone-ua', 'x-mobile-ua', 'device-stock-ua', 'user-agent', 'agent'],
52
51
  'browser-ua-order' => ['user-agent', 'agent', 'device-stock-ua'],
53
52
  'app-ua-order' => ['user-agent', 'agent', 'device-stock-ua'],
54
53
  'language-ua-order' => ['user-agent', 'agent', 'device-stock-ua'],
55
- 'device-bi-order' => {
56
- 'android' => [
57
- ['ro.product.brand','ro.product.model'],
58
- ['ro.product.manufacturer','ro.product.model'],
59
- ['ro-product-brand','ro-product-model'],
60
- ['ro-product-manufacturer','ro-product-model'],
54
+ 'device-bi-order' => {
55
+ 'android' => [
56
+ ['ro.product.brand', 'ro.product.model'],
57
+ ['ro.product.manufacturer', 'ro.product.model'],
58
+ ['ro-product-brand', 'ro-product-model'],
59
+ ['ro-product-manufacturer', 'ro-product-model'],
61
60
  ],
62
- 'ios' => [
63
- ['utsname.brand','utsname.machine']
61
+ 'ios' => [
62
+ ['utsname.brand', 'utsname.machine']
64
63
  ],
65
- 'windows phone' => [
66
- ['devicemanufacturer','devicename']
64
+ 'windows phone' => [
65
+ ['devicemanufacturer', 'devicename']
67
66
  ]
68
67
  },
69
68
  'platform-bi-order' => {
70
- 'android' => [
71
- ['ro.build.id', 'ro.build.version.release'],
72
- ['ro-build-id', 'ro-build-version-release'],
69
+ 'android' => [
70
+ ['hd-platform', 'ro.build.version.release'],
71
+ ['hd-platform', 'ro-build-version-release'],
72
+ ['hd-platform', 'ro.build.id'],
73
+ ['hd-platform', 'ro-build-id'],
73
74
  ],
74
- 'ios' => [
75
- ['uidevice.systemName','uidevice.systemversion']
75
+ 'ios' => [
76
+ ['uidevice.systemname', 'uidevice.systemversion'],
77
+ ['hd-platform', 'uidevice.systemversion']
76
78
  ],
77
- 'windows phone' => [
78
- ['osname','osversion']
79
+ 'windows phone' => [
80
+ ['osname', 'osversion'],
81
+ ['hd-platform', 'osversion']
79
82
  ]
80
83
  },
81
84
  'browser-bi-order' => [],
82
- 'app-bi-order' => []
85
+ 'app-bi-order' => []
83
86
  }
84
- @detection_languages = {
87
+ @detection_languages = {
85
88
  'af' => 'Afrikaans',
86
89
  'sq' => 'Albanian',
87
90
  'ar-dz' => 'Arabic (Algeria)',
@@ -242,15 +245,15 @@ class Base
242
245
 
243
246
  # Get reply status
244
247
  #
245
- # +param+ void
246
- # +return+ int error status, 0 is Ok, anything else is probably not Ok
248
+ # +param+ void
249
+ # +return+ int error status, 0 is Ok, anything else is probably not Ok
247
250
  #
248
251
  def get_status
249
252
  @reply['status']
250
253
  end
251
254
 
252
255
  # Get reply message
253
- #
256
+ #
254
257
  # +param+ void
255
258
  # +return+ string A message
256
259
  #
@@ -274,7 +277,7 @@ class Base
274
277
  #
275
278
  def set_reply(reply)
276
279
  @reply = reply
277
- end
280
+ end
278
281
 
279
282
  # Error handling helper. Sets a message and an error code.
280
283
  #
@@ -287,8 +290,8 @@ class Base
287
290
  @reply['status'] = status
288
291
  @reply['message'] = msg
289
292
  status == 0
290
- end
291
-
293
+ end
294
+
292
295
  # String cleanse for extras matching.
293
296
  #
294
297
  # +param+ string str
@@ -310,7 +313,7 @@ class Base
310
313
  str = str.gsub(/[^\x20-\x7F]/, '')
311
314
  str.strip
312
315
  end
313
-
316
+
314
317
  # Log function - User defined functions can be supplied in the 'logger' config variable.
315
318
  #
316
319
  def log(msg)
@@ -319,7 +322,7 @@ class Base
319
322
  @config['logger'].call(msg)
320
323
  end
321
324
  end
322
-
325
+
323
326
  # Makes requests to the various web services of Handset Detection.
324
327
  #
325
328
  # Note : suburl - the url fragment of the web service eg site/detect/${site_id}
@@ -331,19 +334,19 @@ class Base
331
334
  # +return+ bool true on success, false otherwise
332
335
  #
333
336
  def remote(suburl, data, filetype='json', auth_required=true)
334
- @reply = {}
335
- @raw_reply = {}
337
+ @reply = {}
338
+ @raw_reply = {}
336
339
  set_error 0, ''
337
340
 
338
341
  if data.blank?
339
- data = []
342
+ data = []
340
343
  end
341
344
 
342
345
  url = @api_base + suburl
343
346
  attempts = @config['retries'] + 1
344
347
  trys = 0
345
348
 
346
- requestdata = JSON.generate(data)
349
+ requestdata = JSON.generate(data)
347
350
 
348
351
  success = false
349
352
  while (trys+=1) < attempts and success == false
@@ -419,10 +422,10 @@ class Base
419
422
  'nonce="' + snonce + '", ' +
420
423
  'uri="' + uri.path + '", ' +
421
424
  'qop=' + qop + ', ' +
422
- 'nc=' + nc + ', ' +
425
+ 'nc=' + nc + ', ' +
423
426
  'cnonce="' + cnonce + '", ' +
424
427
  'response="' + response + '", ' +
425
- 'opaque="' + realm + '"' +
428
+ 'opaque="' + realm + '"' +
426
429
  "\r\n"
427
430
  end
428
431
  out += "Content-length: " + jsondata.length.to_s + "\r\n\r\n"
@@ -430,17 +433,22 @@ class Base
430
433
 
431
434
  socket = nil
432
435
  begin
433
- socket = TCPTimeout::TCPSocket.new(host, port,
436
+ socket = TCPTimeout::TCPSocket.new(host, port,
434
437
  connect_timeout: @config['timeout'], read_timeout: @config['timeout'], write_timeout: @config['timeout'])
435
438
  socket.write(out)
436
- reply = socket.read 1000000000
439
+ reply = []
440
+ r = ''
441
+ until r.nil? do
442
+ reply << r
443
+ r = socket.read 8192
444
+ end
437
445
  rescue SocketError => e
438
- return set_error 299, e.to_s
446
+ return set_error 299, e.to_s
439
447
  ensure
440
448
  socket.close unless socket.nil?
441
449
  end
442
- hunks = reply.split("\r\n\r\n")
443
- return set_error(299, "Error : Reply is too short.") if hunks.length < 2
450
+ hunks = reply.join.split("\r\n\r\n")
451
+ return set_error(299, "Error : Reply is too short.") if hunks.length < 2
444
452
  # header = hunks[hunks.length - 2]
445
453
  # headers = header.split("\n")
446
454
  body = hunks[hunks.length - 1]
@@ -544,7 +552,7 @@ class Base
544
552
  # +return+ void
545
553
  #
546
554
  def send_remote_syslog(headers)
547
- headers['version'] = RUBY_VERSION
555
+ headers['version'] = RUBY_VERSION
548
556
  headers['apikit'] = @apikit
549
557
  sock = UDPSocket.new(Socket::AF_INET)
550
558
  message = JSON.generate headers
@@ -41,8 +41,9 @@ class Memcached
41
41
  else
42
42
  options = { 'value_max_bytes' => 4000000 }
43
43
  end
44
- options = options.map {|k, v| [k.to_sym, v]}.to_h
45
- @cache = Dalli::Client.new(servers, options)
44
+ o = {}
45
+ options.each { |k, v| o[k.to_sym] = v }
46
+ @cache = Dalli::Client.new(servers, o)
46
47
  end
47
48
 
48
49
  # Get key
@@ -264,9 +264,14 @@ class Device < Base
264
264
  def specs_overlay(specs_field, device, specs)
265
265
  if specs.include? 'hd_specs'
266
266
  if specs_field == 'platform'
267
- unless specs['hd_specs']['general_platform'].blank?
267
+ unless specs['hd_specs']['general_platform'].blank? or specs['hd_specs']['general_platform_version'].blank?
268
268
  device['Device']['hd_specs']['general_platform'] = specs['hd_specs']['general_platform']
269
269
  device['Device']['hd_specs']['general_platform_version'] = specs['hd_specs']['general_platform_version']
270
+ else
271
+ unless specs['hd_specs']['general_platform'].blank? or specs['hd_specs']['general_platform'] == device['Device']['hd_specs']['general_platform']
272
+ device['Device']['hd_specs']['general_platform'] = specs['hd_specs']['general_platform']
273
+ device['Device']['hd_specs']['general_platform_version'] = ''
274
+ end
270
275
  end
271
276
  elsif specs_field == 'browser'
272
277
  unless specs['hd_specs']['general_browser'].blank?
@@ -451,7 +456,7 @@ class Device < Base
451
456
  # Platform Detection
452
457
  @platform = v4_match_bi_helper build_info, 'platform'
453
458
  unless @platform.blank?
454
- @device = specs_overlay 'platform', @device, @platform
459
+ @device = specs_overlay 'platform', @device, @platform['Extra']
455
460
  end
456
461
 
457
462
  @reply['hd_specs'] = @device['Device']['hd_specs']
@@ -471,11 +476,13 @@ class Device < Base
471
476
 
472
477
  hints = []
473
478
  conf_bi_keys.each do |platform, set|
474
- value = ''
475
479
  set.each do |tuple|
476
480
  checking = true
481
+ value = ''
477
482
  tuple.each do |item|
478
- unless build_info.include? item
483
+ if item == 'hd-platform'
484
+ value += "|#{platform}"
485
+ elsif not build_info.include?(item)
479
486
  checking = false
480
487
  break
481
488
  else
@@ -536,6 +543,7 @@ class Device < Base
536
543
 
537
544
  # Sanitize headers & cleanup language
538
545
  headers.each do |key, value|
546
+ key = key.downcase
539
547
  if key == 'accept-language' or key == 'content-language'
540
548
  key = 'language'
541
549
  tmp = value.downcase.gsub(/ /, '').split(/[,;]/)
@@ -544,9 +552,14 @@ class Device < Base
544
552
  else
545
553
  next
546
554
  end
555
+ elsif key != 'profile' and key != 'x-wap-profile'
556
+ # Handle strings that have had + substituted for a space
557
+ if value.count(' ') == 0 and value.count('+') > 5 and value.length > 20
558
+ value.gsub!('+', ' ')
559
+ end
547
560
  end
548
- @device_headers[key.downcase] = clean_str value
549
- @extra_headers[key.downcase] = @extra.extra_clean_str value
561
+ @device_headers[key] = clean_str value
562
+ @extra_headers[key] = @extra.extra_clean_str value
550
563
  end
551
564
 
552
565
  @device = match_device @device_headers
@@ -327,7 +327,8 @@ class HD4 < Base
327
327
  #
328
328
  def device_detect(data={})
329
329
  id = data['id'].blank? ? @config['site_id'] : data['id']
330
- request_body = @detect_request.merge data
330
+ data.delete 'id'
331
+ request_body = data.blank? ? @detect.request: data
331
332
  fast_key = ''
332
333
 
333
334
  # If caching enabled then check cache
@@ -34,10 +34,7 @@ class Store
34
34
  attr_reader :directory, :cache
35
35
  @@instance = nil
36
36
 
37
- # Singleton Constructor
38
- #
39
- # +param+ string $path Location of storage ROOT dir.
40
- # +param+ boolean $createDirectory - Create storage directory if it does not exist
37
+ # Constructor
41
38
  #
42
39
  def initialize
43
40
  @dirname = "hd40store"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: handset_detection
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Handset Detection
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-09-07 00:00:00.000000000 Z
11
+ date: 2016-10-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Use the HandsetDetection.com API from Ruby.
14
14
  email: hello@handsetdetection.com
@@ -37,17 +37,17 @@ require_paths:
37
37
  - lib
38
38
  required_ruby_version: !ruby/object:Gem::Requirement
39
39
  requirements:
40
- - - ">="
40
+ - - ! '>='
41
41
  - !ruby/object:Gem::Version
42
42
  version: '0'
43
43
  required_rubygems_version: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - ! '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  requirements: []
49
49
  rubyforge_project:
50
- rubygems_version: 2.5.1
50
+ rubygems_version: 2.4.8
51
51
  signing_key:
52
52
  specification_version: 4
53
53
  summary: API kit for HandsetDetection.com