yandex_detector 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+ gemspec
3
+ gem 'rspec'
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&nbsp;— 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,5 @@
1
+ require 'rspec/core/rake_task'
2
+
3
+ RSpec::Core::RakeTask.new('spec')
4
+
5
+ task :default => :spec
@@ -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
@@ -0,0 +1,15 @@
1
+ module YandexDetector
2
+
3
+ module Stats
4
+
5
+ private
6
+
7
+ def measure
8
+ start = Time.now
9
+ yield
10
+ @request_duration = Time.now - start
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,3 @@
1
+ module YandexDetector
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'yandex_detector'
5
+
6
+ RSpec.configure do |config|
7
+ # some (optional) config here
8
+ end
@@ -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