yandex_detector 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/Gemfile +3 -0
- data/README.md +76 -0
- data/Rakefile +5 -0
- data/lib/yandex_detector.rb +16 -0
- data/lib/yandex_detector/config.rb +26 -0
- data/lib/yandex_detector/logger.rb +27 -0
- data/lib/yandex_detector/net.rb +39 -0
- data/lib/yandex_detector/parser.rb +67 -0
- data/lib/yandex_detector/result.rb +48 -0
- data/lib/yandex_detector/result/headers.rb +34 -0
- data/lib/yandex_detector/result/properties.rb +78 -0
- data/lib/yandex_detector/result/stats.rb +15 -0
- data/lib/yandex_detector/version.rb +3 -0
- data/spec/spec_helper.rb +8 -0
- data/spec/yandex_detector/detector_spec_helper.rb +72 -0
- data/spec/yandex_detector/parser_spec_helper.rb +49 -0
- data/spec/yandex_detector/yandex_detector/config_spec.rb +35 -0
- data/spec/yandex_detector/yandex_detector/parser_spec.rb +81 -0
- data/spec/yandex_detector/yandex_detector_spec.rb +58 -0
- data/yandex_detector.gemspec +22 -0
- metadata +94 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# Introduction
|
2
|
+
|
3
|
+
yandex_detector is a Ruby wrapper for Yandex.Detector API (http://api.yandex.ru/detector/) wich allows to detect mobile device's properties by it's request headers.
|
4
|
+
|
5
|
+
This document describes installation and usage of yandex_detector.
|
6
|
+
|
7
|
+
Please report issues on [Github](https://github.com/aishek/yandex_detector/issues).
|
8
|
+
|
9
|
+
For feedback, suggestions, etc. write to <aishek@gmail.com>.
|
10
|
+
|
11
|
+
# Installation
|
12
|
+
|
13
|
+
To install:
|
14
|
+
|
15
|
+
gem install yandex_detector
|
16
|
+
|
17
|
+
or with a Gemfile:
|
18
|
+
|
19
|
+
gem 'yandex_detector'
|
20
|
+
bundle install
|
21
|
+
|
22
|
+
# Usage
|
23
|
+
|
24
|
+
Usage in Rails:
|
25
|
+
|
26
|
+
require 'yandex_detector'
|
27
|
+
|
28
|
+
# API call timeout in seconds (default is 2 seconds)
|
29
|
+
timeout = 2
|
30
|
+
|
31
|
+
result = YandexDetector.detect request.headers, timeout
|
32
|
+
|
33
|
+
Usage in Ruby program:
|
34
|
+
|
35
|
+
require 'yandex_detector'
|
36
|
+
|
37
|
+
# HTTP headers, you need at least one to perform detect
|
38
|
+
headers = Hash.new[
|
39
|
+
'user-agent', 'value1'
|
40
|
+
'profile', 'value2',
|
41
|
+
'wap-profile', 'value3',
|
42
|
+
'x-wap-profile', 'value4',
|
43
|
+
'x-operamini-phone-ua', 'value1'
|
44
|
+
]
|
45
|
+
# API call timeout in seconds (default is 2 seconds)
|
46
|
+
timeout = 2
|
47
|
+
|
48
|
+
result = YandexDetector.detect headers, timeout
|
49
|
+
|
50
|
+
Result object have following helpers:
|
51
|
+
|
52
|
+
result.error?
|
53
|
+
result.error_message
|
54
|
+
|
55
|
+
result.success?
|
56
|
+
result.iphone?
|
57
|
+
result.android?
|
58
|
+
result.blackberry?
|
59
|
+
|
60
|
+
Please, see [complete list of available helpers](http://rubydoc.info/github/aishek/yandex_detector/master/YandexDetector/Properties).
|
61
|
+
|
62
|
+
# Documentation
|
63
|
+
|
64
|
+
The [RubyDoc documentation](http://rubydoc.info/github/aishek/yandex_detector/master/frames) is available online.
|
65
|
+
|
66
|
+
# How it works
|
67
|
+
|
68
|
+
yandex_detector perform Yandex's API service call via network if there are at least one of needed headers provided. Please, consider right timeout value and fallback on timeout for your application to prevent slow execution.
|
69
|
+
|
70
|
+
# Author
|
71
|
+
|
72
|
+
Idea & implementation — Alexandr Borisov (<aishek@gmail.com>)
|
73
|
+
|
74
|
+
# Licence
|
75
|
+
|
76
|
+
yandex_detector is licensed under [MIT](https://github.com/afelix/csso/blob/master/MIT-LICENSE.txt)
|
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "yandex_detector/version"
|
2
|
+
require "yandex_detector/result"
|
3
|
+
|
4
|
+
# @author Alexandr Borisov (aishek@gmail.com)
|
5
|
+
module YandexDetector
|
6
|
+
|
7
|
+
# Performs detectoin by API service call via network if at least one of needed headers specified.
|
8
|
+
#
|
9
|
+
# @param [Hash] headers string-keyed hash of HTTP headers: 'profile', 'wap-profile', 'x-wap-profile', 'user-agent', 'x-operamini-phone-ua'.
|
10
|
+
# @param [Integer, nil] timeout timeout to API service call in seconds
|
11
|
+
# @return [YandexDetector::Result] result detecton object
|
12
|
+
def self.detect(headers, timeout = 2)
|
13
|
+
YandexDetector::Result.new headers, timeout
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module YandexDetector
|
2
|
+
|
3
|
+
class Config
|
4
|
+
|
5
|
+
# URL of API service according documentation {http://api.yandex.ru/detector/doc/dg/concepts/detector-request.xml}
|
6
|
+
API_URL = 'http://phd.yandex.net/detect/'
|
7
|
+
# Error's tag name according documentation {http://api.yandex.ru/detector/doc/dg/concepts/detector-response.xml}
|
8
|
+
ERROR_TAG_NAME = 'yandex-mobile-info-error'
|
9
|
+
|
10
|
+
# @private
|
11
|
+
@@timeout = 2
|
12
|
+
|
13
|
+
# @return [Integer] timeout in seconds to API service call
|
14
|
+
def self.timeout
|
15
|
+
@@timeout
|
16
|
+
end
|
17
|
+
|
18
|
+
# Set timeout value to API service call in seconds only if integer value passed
|
19
|
+
# @param [Integer] timeout_value specify timeout value in seconds
|
20
|
+
def self.timeout=(timeout_value = nil)
|
21
|
+
@@timeout = timeout_value if timeout_value.is_a?(Integer)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module YandexDetector
|
2
|
+
|
3
|
+
class Result
|
4
|
+
|
5
|
+
class Logger
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def log(result, request_duration)
|
10
|
+
log_info result
|
11
|
+
log_info "Request to Yandex.Detector API completed in #{request_duration}"
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def log_info(message)
|
18
|
+
Rails.logger.info message if defined?(Rails)
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'yandex_detector/config'
|
2
|
+
require 'net/http'
|
3
|
+
require 'uri'
|
4
|
+
|
5
|
+
module YandexDetector
|
6
|
+
|
7
|
+
class Net
|
8
|
+
|
9
|
+
class << self
|
10
|
+
|
11
|
+
def send_detect_request(headers)
|
12
|
+
result = nil
|
13
|
+
uri = URI.parse(prepare_url(headers))
|
14
|
+
|
15
|
+
if YandexDetector::Config.timeout > 0
|
16
|
+
begin
|
17
|
+
timeout YandexDetector::Config.timeout do
|
18
|
+
result = ::Net::HTTP.get uri
|
19
|
+
end
|
20
|
+
rescue
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
result
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def prepare_url(headers)
|
31
|
+
query = headers.collect {|pair| "#{URI.encode_www_form_component(pair[0])}=#{URI.encode_www_form_component(pair[1])}" }.join('&')
|
32
|
+
"#{YandexDetector::Config::API_URL}?#{query}"
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
module YandexDetector
|
4
|
+
|
5
|
+
class Parser
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def parse(result)
|
10
|
+
error_present?(result) ? parse_error(result) : parse_success(result)
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def parse_error(result)
|
17
|
+
error = match_tag_content(result, YandexDetector::Config::ERROR_TAG_NAME) if result_present?(result)
|
18
|
+
{
|
19
|
+
:text => result,
|
20
|
+
:error => error
|
21
|
+
}
|
22
|
+
end
|
23
|
+
|
24
|
+
def result_present?(result)
|
25
|
+
!result.nil? and !result.strip.empty?
|
26
|
+
end
|
27
|
+
|
28
|
+
def error_present?(result)
|
29
|
+
!result_present?(result) or result.include?(YandexDetector::Config::ERROR_TAG_NAME)
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_success(result)
|
33
|
+
begin
|
34
|
+
{
|
35
|
+
:text => result,
|
36
|
+
:data => {
|
37
|
+
:yandex_mobile_info => {
|
38
|
+
:name => match_tag_content(result, 'name'),
|
39
|
+
:vendor => match_tag_content(result, 'vendor'),
|
40
|
+
:device_class => match_tag_content(result, 'device-class'),
|
41
|
+
:device_class_desc => match_tag_content(result, 'device-class-desc'),
|
42
|
+
:screenx => match_tag_content(result, 'screenx'),
|
43
|
+
:screeny => match_tag_content(result, 'screeny'),
|
44
|
+
:java => {
|
45
|
+
:cam_access => match_tag_content(result, 'cam-access'),
|
46
|
+
:fs_accesss => match_tag_content(result, 'fs-access'),
|
47
|
+
:certificate_prefix => match_tag_content(result, 'certificate-prefix'),
|
48
|
+
:iconsize => match_tag_content(result, 'iconsize')
|
49
|
+
}
|
50
|
+
}
|
51
|
+
}
|
52
|
+
}
|
53
|
+
rescue
|
54
|
+
parse_error result
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def match_tag_content(result, tagname)
|
59
|
+
matches = result.match("<#{tagname}>(.*)</#{tagname}>")
|
60
|
+
!matches.nil? and matches.length > 1 ? matches[1] : ""
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'yandex_detector/config'
|
2
|
+
require 'yandex_detector/net'
|
3
|
+
require 'yandex_detector/parser'
|
4
|
+
require 'yandex_detector/logger'
|
5
|
+
|
6
|
+
require 'yandex_detector/result/headers'
|
7
|
+
require 'yandex_detector/result/properties'
|
8
|
+
require 'yandex_detector/result/stats'
|
9
|
+
|
10
|
+
module YandexDetector
|
11
|
+
|
12
|
+
class Result
|
13
|
+
include YandexDetector::Headers
|
14
|
+
include YandexDetector::Properties
|
15
|
+
include YandexDetector::Stats
|
16
|
+
|
17
|
+
attr_reader :error, :data, :request_duration
|
18
|
+
|
19
|
+
def initialize(request, timeout = 2)
|
20
|
+
YandexDetector::Config.timeout = timeout
|
21
|
+
|
22
|
+
init_headers request
|
23
|
+
|
24
|
+
@request_performed = false
|
25
|
+
detect
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def detect
|
32
|
+
return unless headers_present?
|
33
|
+
|
34
|
+
result = nil
|
35
|
+
measure do
|
36
|
+
result = YandexDetector::Net.send_detect_request @headers
|
37
|
+
end
|
38
|
+
|
39
|
+
unless result.nil?
|
40
|
+
Logger::log result, request_duration
|
41
|
+
@data = YandexDetector::Parser.parse result
|
42
|
+
@request_performed = true
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module YandexDetector
|
2
|
+
|
3
|
+
module Headers
|
4
|
+
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
def init_headers(headers)
|
9
|
+
@headers = create_headers headers
|
10
|
+
end
|
11
|
+
|
12
|
+
def headers_present?
|
13
|
+
!@headers.empty?
|
14
|
+
end
|
15
|
+
|
16
|
+
def create_headers(headers)
|
17
|
+
result = []
|
18
|
+
|
19
|
+
push_header_if_present result, headers, 'profile'
|
20
|
+
push_header_if_present result, headers, 'wap-profile'
|
21
|
+
push_header_if_present result, headers, 'x-wap-profile'
|
22
|
+
push_header_if_present result, headers, 'user-agent'
|
23
|
+
push_header_if_present result, headers, 'x-operamini-phone-ua'
|
24
|
+
|
25
|
+
result
|
26
|
+
end
|
27
|
+
|
28
|
+
def push_header_if_present(result, headers, header)
|
29
|
+
result << [header, headers[header]] unless headers[header].nil? or headers[header].strip.empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module YandexDetector
|
2
|
+
|
3
|
+
# This module contain YandexDetector::Result instance's methods, which allow to determine concrete properties of result
|
4
|
+
module Properties
|
5
|
+
|
6
|
+
# @return [Bool] network request to API service was performed
|
7
|
+
def request_performed?
|
8
|
+
@request_performed
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
# @return [Bool] any error occured
|
13
|
+
def error?
|
14
|
+
!request_performed? or @data.nil? or !@data[:error].nil?
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [String, nil] error message if present, or nil otherwise
|
18
|
+
def error_message
|
19
|
+
begin
|
20
|
+
@data[:error]
|
21
|
+
rescue
|
22
|
+
nil
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Bool] no error occured
|
27
|
+
def success?
|
28
|
+
!error?
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
# @return [Bool] iphone detected
|
33
|
+
def iphone?
|
34
|
+
device_class === 'iphoneos'
|
35
|
+
end
|
36
|
+
|
37
|
+
# @return [Bool] android detected
|
38
|
+
def android?
|
39
|
+
device_class === 'android'
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [Bool] blackberry detected
|
43
|
+
def blackberry?
|
44
|
+
device_class === 'rim'
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
# @return [String, nil] device_class string according to documentation {http://api.yandex.ru/detector/doc/dg/concepts/detector-response.xml}
|
49
|
+
def device_class
|
50
|
+
begin
|
51
|
+
@data[:data][:yandex_mobile_info][:device_class]
|
52
|
+
rescue
|
53
|
+
nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Hash] Hash representation of API service's answer according to documentation {http://api.yandex.ru/detector/doc/dg/concepts/detector-response.xml}.
|
58
|
+
# All '-' signs in tag names replaced by '_' and tag names converted to symbols to use as Hash's keys.
|
59
|
+
def data
|
60
|
+
begin
|
61
|
+
@data[:data]
|
62
|
+
rescue
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [String] Text representation of API service's answer according to documentation {http://api.yandex.ru/detector/doc/dg/concepts/detector-response.xml}.
|
68
|
+
def text
|
69
|
+
begin
|
70
|
+
@data[:text]
|
71
|
+
rescue
|
72
|
+
nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
module DetectorSpecHelper
|
2
|
+
|
3
|
+
def should_provide_result_on(headers)
|
4
|
+
result = YandexDetector.detect headers
|
5
|
+
result.should be_an_instance_of(YandexDetector::Result)
|
6
|
+
result
|
7
|
+
end
|
8
|
+
|
9
|
+
def should_result_on(headers, options = { :request_performed => true, :error => false, :success => true })
|
10
|
+
result = should_provide_result_on headers
|
11
|
+
result = check_properties result, options
|
12
|
+
|
13
|
+
result
|
14
|
+
end
|
15
|
+
|
16
|
+
def check_properties(result, options = { :request_performed => true, :error => false, :success => true })
|
17
|
+
result.request_performed?.should(eql(options[:request_performed]), "request_performed? flag not equals to #{options[:request_performed]}") unless options[:request_performed].nil?
|
18
|
+
|
19
|
+
result.error?.should(eql(options[:error]), "error? flag not equals to #{options[:error]}") unless options[:error].nil?
|
20
|
+
result.success?.should(eql(options[:success]), "success? flag not equals to #{options[:success]}") unless options[:success].nil?
|
21
|
+
|
22
|
+
result
|
23
|
+
end
|
24
|
+
|
25
|
+
def android_headers
|
26
|
+
Hash[
|
27
|
+
'user-agent', 'Mozilla/5.0 (Linux; U; Android 2.3.3; pl-pl; HTC Vision Build/GRI40) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1'
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
31
|
+
def blackberry_headers
|
32
|
+
Hash[
|
33
|
+
'user-agent', 'BlackBerry9700/5.0.0.862 Profile/MIDP-2.1 Configuration/CLDC-1.1 VendorID/120'
|
34
|
+
]
|
35
|
+
end
|
36
|
+
|
37
|
+
def iphone_headers
|
38
|
+
Hash[
|
39
|
+
'user-agent', 'Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A543a Safari/419.3'
|
40
|
+
]
|
41
|
+
end
|
42
|
+
|
43
|
+
def valid_headers
|
44
|
+
Hash[
|
45
|
+
'user-agent', 'Alcatel-CTH3/1.0 UP.Browser/6.2.ALCATEL MMP/1.0',
|
46
|
+
'wap-profile', 'http://www-ccpp-mpd.alcatel.com/files/ALCATEL-CTH3_MMS10_1.0.rdf'
|
47
|
+
]
|
48
|
+
end
|
49
|
+
|
50
|
+
def headers_with_unknown_values
|
51
|
+
Hash[
|
52
|
+
'user-agent', 'unknown'
|
53
|
+
]
|
54
|
+
end
|
55
|
+
|
56
|
+
def empty_headers
|
57
|
+
Hash.new
|
58
|
+
end
|
59
|
+
|
60
|
+
def wrong_headers
|
61
|
+
Hash['test-header', 'test-value']
|
62
|
+
end
|
63
|
+
|
64
|
+
def headers_with_whitespaces_values
|
65
|
+
Hash[
|
66
|
+
'profile', '',
|
67
|
+
'user-agent', "\t\t\n\r\n\r",
|
68
|
+
'wap-profile', ' '
|
69
|
+
]
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module ParserSpecHelper
|
3
|
+
|
4
|
+
def error_xml_text
|
5
|
+
error_text = 'my brand new error'
|
6
|
+
[error_text, "<#{YandexDetector::Config::ERROR_TAG_NAME}>#{error_text}</#{YandexDetector::Config::ERROR_TAG_NAME}>"]
|
7
|
+
end
|
8
|
+
|
9
|
+
def result_xml_text
|
10
|
+
"<yandex-mobile-info>
|
11
|
+
<name>One Touch C651</name><!-- название модели телефона -->
|
12
|
+
<vendor>Alcatel</vendor><!-- название производителя телефона -->
|
13
|
+
<device-class>midp2ss</device-class><!-- класс устройства -->
|
14
|
+
<device-class-desc>Java MIDP2 (small)</device-class-desc><!-- описание класса устройства -->
|
15
|
+
<screenx>128</screenx><!-- разрешение экрана в пикселах по ширине -->
|
16
|
+
<screeny>160</screeny><!-- разрешение экрана в пикселах по высоте -->
|
17
|
+
<java><!-- контейнер для Java-параметров -->
|
18
|
+
<cam-access>1</cam-access><!-- есть ли у Java-приложений доступ к камере устройства -->
|
19
|
+
<fs-access>1</fs-access><!-- есть ли у Java-приложений доступ к файловой системе устройства -->
|
20
|
+
<certificate-prefix></certificate-prefix> <!-- префикс Java-сертификата -->
|
21
|
+
<iconsize>18x18</iconsize><!-- размер значка Java-приложения -->
|
22
|
+
</java>
|
23
|
+
</yandex-mobile-info>"
|
24
|
+
end
|
25
|
+
|
26
|
+
def result_xml_text_data
|
27
|
+
{
|
28
|
+
:yandex_mobile_info => {
|
29
|
+
:name => "One Touch C651",
|
30
|
+
:vendor => "Alcatel",
|
31
|
+
:device_class => "midp2ss",
|
32
|
+
:device_class_desc => "Java MIDP2 (small)",
|
33
|
+
:screenx => "128",
|
34
|
+
:screeny => "160",
|
35
|
+
:java => {
|
36
|
+
:cam_access => "1",
|
37
|
+
:fs_accesss => "1",
|
38
|
+
:certificate_prefix => "",
|
39
|
+
:iconsize=>"18x18"
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
def result_whitespaces
|
46
|
+
"\r\n\t\ \n"
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
describe YandexDetector do
|
3
|
+
|
4
|
+
describe YandexDetector::Config do
|
5
|
+
|
6
|
+
it "should set timeout only for integer" do
|
7
|
+
first_value = YandexDetector::Config::timeout
|
8
|
+
|
9
|
+
YandexDetector::Config::timeout = nil
|
10
|
+
YandexDetector::Config::timeout.should == first_value
|
11
|
+
|
12
|
+
YandexDetector::Config::timeout = 'a'
|
13
|
+
YandexDetector::Config::timeout.should == first_value
|
14
|
+
|
15
|
+
YandexDetector::Config::timeout = Object.new
|
16
|
+
YandexDetector::Config::timeout.should == first_value
|
17
|
+
|
18
|
+
YandexDetector::Config::timeout = 0.2
|
19
|
+
YandexDetector::Config::timeout.should == first_value
|
20
|
+
|
21
|
+
YandexDetector::Config::timeout = first_value + 1
|
22
|
+
YandexDetector::Config::timeout.should == first_value + 1
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should define corrent API_URL" do
|
26
|
+
YandexDetector::Config::API_URL.should == "http://phd.yandex.net/detect/"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should define corrent ERROR_TAG_NAME" do
|
30
|
+
YandexDetector::Config::ERROR_TAG_NAME.should == "yandex-mobile-info-error"
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'yandex_detector/parser_spec_helper'
|
3
|
+
|
4
|
+
describe YandexDetector do
|
5
|
+
include ParserSpecHelper
|
6
|
+
|
7
|
+
describe YandexDetector::Parser do
|
8
|
+
|
9
|
+
it "should return hash" do
|
10
|
+
result = YandexDetector::Parser.parse nil
|
11
|
+
result.should be_an_instance_of(Hash)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return error key on nil result" do
|
15
|
+
result = YandexDetector::Parser.parse nil
|
16
|
+
|
17
|
+
result.should be_an_instance_of(Hash)
|
18
|
+
|
19
|
+
result.should have_key(:error)
|
20
|
+
result.should_not have_key(:data)
|
21
|
+
|
22
|
+
result.should have_key(:text)
|
23
|
+
result[:text].should == nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should return error key on whitespaces result" do
|
27
|
+
result = YandexDetector::Parser.parse result_whitespaces
|
28
|
+
|
29
|
+
result.should be_an_instance_of(Hash)
|
30
|
+
|
31
|
+
result.should have_key(:error)
|
32
|
+
result.should_not have_key(:data)
|
33
|
+
|
34
|
+
result.should have_key(:text)
|
35
|
+
result[:text].should == result_whitespaces
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should return error text in error tag present" do
|
39
|
+
error_text, xml_text = error_xml_text
|
40
|
+
|
41
|
+
result = YandexDetector::Parser.parse xml_text
|
42
|
+
|
43
|
+
result.should be_an_instance_of(Hash)
|
44
|
+
|
45
|
+
result.should have_key(:error)
|
46
|
+
result.should_not have_key(:data)
|
47
|
+
|
48
|
+
result[:error].should == error_text
|
49
|
+
|
50
|
+
result.should have_key(:text)
|
51
|
+
result[:text].should == xml_text
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should return data key in hash if result passed" do
|
55
|
+
result = YandexDetector::Parser.parse result_xml_text
|
56
|
+
|
57
|
+
result.should be_an_instance_of(Hash)
|
58
|
+
|
59
|
+
result.should_not have_key(:error)
|
60
|
+
result.should have_key(:data)
|
61
|
+
|
62
|
+
result.should have_key(:text)
|
63
|
+
result[:text].should == result_xml_text
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should return equals hash by data key in hash if result passed" do
|
67
|
+
result = YandexDetector::Parser.parse result_xml_text
|
68
|
+
|
69
|
+
result.should be_an_instance_of(Hash)
|
70
|
+
|
71
|
+
result.should_not have_key(:error)
|
72
|
+
result.should have_key(:data)
|
73
|
+
result[:data].should == result_xml_text_data
|
74
|
+
|
75
|
+
result.should have_key(:text)
|
76
|
+
result[:text].should == result_xml_text
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'yandex_detector/detector_spec_helper'
|
3
|
+
|
4
|
+
describe YandexDetector do
|
5
|
+
include DetectorSpecHelper
|
6
|
+
|
7
|
+
it "should provide result on empty" do
|
8
|
+
should_provide_result_on empty_headers
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should raise ArgumentError on empty" do
|
12
|
+
expect {
|
13
|
+
YandexDetector.detect
|
14
|
+
}.to raise_error(ArgumentError)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should apply timeout" do
|
18
|
+
result = YandexDetector.detect iphone_headers, 0
|
19
|
+
check_properties result, { :request_performed => false, :success => false, :error => true }
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should provide result on wrong headers" do
|
23
|
+
should_result_on wrong_headers, :request_performed => false, :success => false, :error => true
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should provide result and error message on unknown header value" do
|
27
|
+
result = should_result_on headers_with_unknown_values, :request_performed => true, :success => false, :error => true
|
28
|
+
result.error_message.should_not eql(nil)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should no net request perform on empty" do
|
32
|
+
should_result_on empty_headers, :request_performed => false, :success => false, :error => true
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should no net request perform on headers with whitespace-values" do
|
36
|
+
should_result_on headers_with_whitespaces_values, :request_performed => false, :success => false, :error => true
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should provide result on valid" do
|
40
|
+
should_result_on valid_headers
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should provide result on iphone headers" do
|
44
|
+
result = should_result_on iphone_headers
|
45
|
+
result.iphone?.should eql(true)
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should provide result on blackberry headers" do
|
49
|
+
result = should_result_on blackberry_headers
|
50
|
+
result.blackberry?.should eql(true)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should provide result on android" do
|
54
|
+
result = should_result_on android_headers
|
55
|
+
result.android?.should eql(true)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "yandex_detector/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "yandex_detector"
|
7
|
+
s.version = YandexDetector::VERSION
|
8
|
+
s.authors = ["Alexandr Borisov"]
|
9
|
+
s.email = ["aishek@gmail.com"]
|
10
|
+
s.platform = Gem::Platform::RUBY
|
11
|
+
s.homepage = "http://github.com/aishek/yandex_detector"
|
12
|
+
s.summary = %q{yandex_detector is a gem, wich uses Yandex.Detector API to detect via request's headers.}
|
13
|
+
s.description = %q{yandex_detector is a gem, wich uses Yandex.Detector API to detect via request's headers (see http://api.yandex.ru/detector/).}
|
14
|
+
s.license = 'MIT'
|
15
|
+
|
16
|
+
s.rubyforge_project = "yandex_detector"
|
17
|
+
|
18
|
+
s.files = `git ls-files`.split("\n")
|
19
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
end
|
metadata
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: yandex_detector
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Alexandr Borisov
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-10-14 00:00:00 +04:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: yandex_detector is a gem, wich uses Yandex.Detector API to detect via request's headers (see http://api.yandex.ru/detector/).
|
23
|
+
email:
|
24
|
+
- aishek@gmail.com
|
25
|
+
executables: []
|
26
|
+
|
27
|
+
extensions: []
|
28
|
+
|
29
|
+
extra_rdoc_files: []
|
30
|
+
|
31
|
+
files:
|
32
|
+
- .gitignore
|
33
|
+
- .rspec
|
34
|
+
- Gemfile
|
35
|
+
- README.md
|
36
|
+
- Rakefile
|
37
|
+
- lib/yandex_detector.rb
|
38
|
+
- lib/yandex_detector/config.rb
|
39
|
+
- lib/yandex_detector/logger.rb
|
40
|
+
- lib/yandex_detector/net.rb
|
41
|
+
- lib/yandex_detector/parser.rb
|
42
|
+
- lib/yandex_detector/result.rb
|
43
|
+
- lib/yandex_detector/result/headers.rb
|
44
|
+
- lib/yandex_detector/result/properties.rb
|
45
|
+
- lib/yandex_detector/result/stats.rb
|
46
|
+
- lib/yandex_detector/version.rb
|
47
|
+
- spec/spec_helper.rb
|
48
|
+
- spec/yandex_detector/detector_spec_helper.rb
|
49
|
+
- spec/yandex_detector/parser_spec_helper.rb
|
50
|
+
- spec/yandex_detector/yandex_detector/config_spec.rb
|
51
|
+
- spec/yandex_detector/yandex_detector/parser_spec.rb
|
52
|
+
- spec/yandex_detector/yandex_detector_spec.rb
|
53
|
+
- yandex_detector.gemspec
|
54
|
+
has_rdoc: true
|
55
|
+
homepage: http://github.com/aishek/yandex_detector
|
56
|
+
licenses:
|
57
|
+
- MIT
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 3
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project: yandex_detector
|
84
|
+
rubygems_version: 1.4.2
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: yandex_detector is a gem, wich uses Yandex.Detector API to detect via request's headers.
|
88
|
+
test_files:
|
89
|
+
- spec/spec_helper.rb
|
90
|
+
- spec/yandex_detector/detector_spec_helper.rb
|
91
|
+
- spec/yandex_detector/parser_spec_helper.rb
|
92
|
+
- spec/yandex_detector/yandex_detector/config_spec.rb
|
93
|
+
- spec/yandex_detector/yandex_detector/parser_spec.rb
|
94
|
+
- spec/yandex_detector/yandex_detector_spec.rb
|