wurfl_cloud_client 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +40 -0
- data/Rakefile +19 -0
- data/lib/wurfl_cloud.rb +49 -0
- data/lib/wurfl_cloud/cache/cookie.rb +43 -0
- data/lib/wurfl_cloud/cache/local_memory.rb +43 -0
- data/lib/wurfl_cloud/cache/memcached.rb +64 -0
- data/lib/wurfl_cloud/cache/null.rb +41 -0
- data/lib/wurfl_cloud/cache/rails.rb +56 -0
- data/lib/wurfl_cloud/client.rb +105 -0
- data/lib/wurfl_cloud/configuration.rb +88 -0
- data/lib/wurfl_cloud/device_capabilities.rb +78 -0
- data/lib/wurfl_cloud/environment.rb +48 -0
- data/lib/wurfl_cloud/errors.rb +23 -0
- data/lib/wurfl_cloud/helper.rb +21 -0
- data/lib/wurfl_cloud/rack/cache_manager.rb +54 -0
- data/lib/wurfl_cloud/rails.rb +34 -0
- data/lib/wurfl_cloud/version.rb +14 -0
- data/spec/files/generic.json +1 -0
- data/spec/files/generic_filtered.json +1 -0
- data/spec/files/lumia.json +1 -0
- data/spec/files/lumia_filtered.json +1 -0
- data/spec/files/strange_values.json +1 -0
- data/spec/spec_helper.rb +27 -0
- data/spec/support/rack_helpers.rb +79 -0
- data/spec/support/string_extensions.rb +33 -0
- data/spec/wurfl_cloud/client_spec.rb +207 -0
- data/spec/wurfl_cloud/configuration_spec.rb +118 -0
- data/spec/wurfl_cloud/cookie_cache_spec.rb +51 -0
- data/spec/wurfl_cloud/device_capabilities_spec.rb +143 -0
- data/spec/wurfl_cloud/environment_spec.rb +93 -0
- data/spec/wurfl_cloud/helper_spec.rb +35 -0
- data/spec/wurfl_cloud/memcached_cache_spec.rb +122 -0
- data/spec/wurfl_cloud/null_cache_spec.rb +37 -0
- data/spec/wurfl_cloud/rack_cache_manager_spec.rb +76 -0
- data/spec/wurfl_cloud/rails_cache_spec.rb +126 -0
- data/spec/wurfl_cloud/server_request_spec.rb +45 -0
- data/wurfl_cloud_client.gemspec +38 -0
- metadata +171 -0
@@ -0,0 +1,88 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2015 ScientiaMobile Inc.
|
3
|
+
#
|
4
|
+
# The WURFL Cloud Client is intended to be used in both open-source and
|
5
|
+
# commercial environments. To allow its use in as many situations as possible,
|
6
|
+
# the WURFL Cloud Client is dual-licensed. You may choose to use the WURFL
|
7
|
+
# Cloud Client under either the GNU GENERAL PUBLIC LICENSE, Version 2.0, or
|
8
|
+
# the MIT License.
|
9
|
+
#
|
10
|
+
# Refer to the COPYING.txt file distributed with this package.
|
11
|
+
#
|
12
|
+
require 'wurfl_cloud/errors'
|
13
|
+
|
14
|
+
module WurflCloud
|
15
|
+
class Configuration
|
16
|
+
# The API key to access the WurflCloud api (defaults to "100000:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx").
|
17
|
+
attr_accessor :api_key
|
18
|
+
|
19
|
+
# The API user id decoded from the api_key
|
20
|
+
attr_reader :api_user
|
21
|
+
|
22
|
+
# The API password decoded from the api_key
|
23
|
+
attr_reader :api_password
|
24
|
+
|
25
|
+
# The schema of the URI for the api server (defaults to http).
|
26
|
+
attr_accessor :schema
|
27
|
+
|
28
|
+
# The host to connect to (defaults to api.wurflcloud.com).
|
29
|
+
attr_accessor :host
|
30
|
+
|
31
|
+
# The port on which your WurflCloud server runs (defaults to 80).
|
32
|
+
attr_accessor :port
|
33
|
+
|
34
|
+
# The path (URL) for the API endpoint at the host (defaults to /v1/json).
|
35
|
+
attr_accessor :path
|
36
|
+
|
37
|
+
# The API Type, defaults to http (*not used*)
|
38
|
+
attr_accessor :api_type
|
39
|
+
|
40
|
+
# The search parameter format (defaults to "search:(%{capabilities})")
|
41
|
+
attr_accessor :search_parameter
|
42
|
+
|
43
|
+
# The search parameter capabilities separator (defaults to ",")
|
44
|
+
attr_accessor :search_parameter_separator
|
45
|
+
|
46
|
+
# The cache class to be used (defaults to a WurflCloud::Cache::Null )
|
47
|
+
attr_accessor :cache_class
|
48
|
+
|
49
|
+
# The cache_options to be used (defaults to {})
|
50
|
+
attr_accessor :cache_options
|
51
|
+
|
52
|
+
def initialize
|
53
|
+
@api_key = "100000:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
54
|
+
@api_user = 100000
|
55
|
+
@api_password = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
56
|
+
@host = 'api.wurflcloud.com'
|
57
|
+
@schema = 'http'
|
58
|
+
@port = 80
|
59
|
+
@path = '/v1/json'
|
60
|
+
@api_type = 'http'
|
61
|
+
@search_parameter = "search:(%{capabilities})"
|
62
|
+
@search_parameter_separator = ','
|
63
|
+
@cache_class = WurflCloud::Cache::Null
|
64
|
+
@cache_options = {}
|
65
|
+
end
|
66
|
+
|
67
|
+
def api_key=(new_key)
|
68
|
+
@api_key = new_key
|
69
|
+
if new_key=~/^(\d{6}):(\w{32})$/
|
70
|
+
@api_user = $1.to_i
|
71
|
+
@api_password = $2
|
72
|
+
else
|
73
|
+
raise WurflCloud::Errors::ConfigurationError.new
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def api_uri
|
78
|
+
"#{@schema}://#{@host}:#{@port}#{@path}"
|
79
|
+
end
|
80
|
+
|
81
|
+
# creates a cache instance using the class and the options
|
82
|
+
# given in the confinguration and passing whatever environment
|
83
|
+
# is passed in the parameters
|
84
|
+
def cache(environment)
|
85
|
+
@cache_class.new(@cache_options, environment)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2015 ScientiaMobile Inc.
|
3
|
+
#
|
4
|
+
# The WURFL Cloud Client is intended to be used in both open-source and
|
5
|
+
# commercial environments. To allow its use in as many situations as possible,
|
6
|
+
# the WURFL Cloud Client is dual-licensed. You may choose to use the WURFL
|
7
|
+
# Cloud Client under either the GNU GENERAL PUBLIC LICENSE, Version 2.0, or
|
8
|
+
# the MIT License.
|
9
|
+
#
|
10
|
+
# Refer to the COPYING.txt file distributed with this package.
|
11
|
+
#
|
12
|
+
require 'wurfl_cloud/errors'
|
13
|
+
require 'json'
|
14
|
+
|
15
|
+
module WurflCloud
|
16
|
+
class DeviceCapabilities
|
17
|
+
attr_accessor :mtime, :id, :user_agent
|
18
|
+
|
19
|
+
def initialize(ua = nil)
|
20
|
+
@capabilities = {}
|
21
|
+
@mtime = Time.at(0)
|
22
|
+
@id = nil
|
23
|
+
@user_agent = ua
|
24
|
+
end
|
25
|
+
|
26
|
+
def [](key)
|
27
|
+
@capabilities[key]
|
28
|
+
end
|
29
|
+
|
30
|
+
def []=(key, value)
|
31
|
+
@capabilities[key] = value
|
32
|
+
end
|
33
|
+
|
34
|
+
def merge(newvalues)
|
35
|
+
@capabilities.merge!(newvalues)
|
36
|
+
end
|
37
|
+
|
38
|
+
def empty?
|
39
|
+
@capabilities.empty?
|
40
|
+
end
|
41
|
+
|
42
|
+
def has_key?(key)
|
43
|
+
@capabilities.has_key?(key)
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_hash
|
47
|
+
@capabilities.clone
|
48
|
+
end
|
49
|
+
class << self
|
50
|
+
def parse(json)
|
51
|
+
object = JSON.parse(json)
|
52
|
+
new.tap do |device_capabilities|
|
53
|
+
object["capabilities"].each do |key,value|
|
54
|
+
device_capabilities[key] = cast_value(value)
|
55
|
+
end
|
56
|
+
|
57
|
+
device_capabilities.id = object["id"]
|
58
|
+
device_capabilities["id"] = object["id"]
|
59
|
+
device_capabilities.mtime = Time.at(object["mtime"].to_i)
|
60
|
+
end
|
61
|
+
rescue
|
62
|
+
raise WurflCloud::Errors::MalformedResponseError.new
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def cast_value(value)
|
68
|
+
case value.to_s
|
69
|
+
when "true" then true ;
|
70
|
+
when "false" then false ;
|
71
|
+
when /^[1-9][0-9]*$/ then value.to_s.to_i ;
|
72
|
+
when /^[1-9][0-9]*\.[0-9]+$/ then value.to_s.to_f ;
|
73
|
+
else value
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2015 ScientiaMobile Inc.
|
3
|
+
#
|
4
|
+
# The WURFL Cloud Client is intended to be used in both open-source and
|
5
|
+
# commercial environments. To allow its use in as many situations as possible,
|
6
|
+
# the WURFL Cloud Client is dual-licensed. You may choose to use the WURFL
|
7
|
+
# Cloud Client under either the GNU GENERAL PUBLIC LICENSE, Version 2.0, or
|
8
|
+
# the MIT License.
|
9
|
+
#
|
10
|
+
# Refer to the COPYING.txt file distributed with this package.
|
11
|
+
#
|
12
|
+
require 'wurfl_cloud/errors'
|
13
|
+
|
14
|
+
module WurflCloud
|
15
|
+
class Environment
|
16
|
+
|
17
|
+
USER_AGENT_FIELDS = [
|
18
|
+
'HTTP_X_DEVICE_USER_AGENT',
|
19
|
+
'HTTP_X_ORIGINAL_USER_AGENT',
|
20
|
+
'HTTP_X_OPERAMINI_PHONE_UA',
|
21
|
+
'HTTP_X_SKYFIRE_PHONE',
|
22
|
+
'HTTP_X_BOLT_PHONE_UA',
|
23
|
+
'HTTP_USER_AGENT'
|
24
|
+
]
|
25
|
+
|
26
|
+
attr_reader :user_agent, :x_forwarded_for, :x_accept, :x_wap_profile
|
27
|
+
|
28
|
+
# Extracts the http headers that are relevant
|
29
|
+
# to the library. They are used by the client
|
30
|
+
# when communicating with the API server.
|
31
|
+
def initialize(http_env={})
|
32
|
+
USER_AGENT_FIELDS.each do |ua_field|
|
33
|
+
@user_agent ||= http_env[ua_field]
|
34
|
+
end
|
35
|
+
|
36
|
+
@x_accept = http_env["HTTP_ACCEPT"]
|
37
|
+
|
38
|
+
if !(@x_wap_profile = http_env["HTTP_X_WAP_PROFILE"])
|
39
|
+
@x_wap_profile = http_env["HTTP_PROFILE"]
|
40
|
+
end
|
41
|
+
|
42
|
+
if http_env["REMOTE_ADDR"]
|
43
|
+
@x_forwarded_for = http_env["REMOTE_ADDR"]
|
44
|
+
@x_forwarded_for = "#{x_forwarded_for}, #{http_env["HTTP_X_FORWARDED_FOR"]}" if http_env["HTTP_X_FORWARDED_FOR"]
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2015 ScientiaMobile Inc.
|
3
|
+
#
|
4
|
+
# The WURFL Cloud Client is intended to be used in both open-source and
|
5
|
+
# commercial environments. To allow its use in as many situations as possible,
|
6
|
+
# the WURFL Cloud Client is dual-licensed. You may choose to use the WURFL
|
7
|
+
# Cloud Client under either the GNU GENERAL PUBLIC LICENSE, Version 2.0, or
|
8
|
+
# the MIT License.
|
9
|
+
#
|
10
|
+
# Refer to the COPYING.txt file distributed with this package.
|
11
|
+
#
|
12
|
+
module WurflCloud
|
13
|
+
module Errors
|
14
|
+
class GenericError < StandardError
|
15
|
+
end
|
16
|
+
class MalformedResponseError < GenericError
|
17
|
+
end
|
18
|
+
class ConfigurationError < GenericError
|
19
|
+
end
|
20
|
+
class ConnectionError < GenericError
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2015 ScientiaMobile Inc.
|
3
|
+
#
|
4
|
+
# The WURFL Cloud Client is intended to be used in both open-source and
|
5
|
+
# commercial environments. To allow its use in as many situations as possible,
|
6
|
+
# the WURFL Cloud Client is dual-licensed. You may choose to use the WURFL
|
7
|
+
# Cloud Client under either the GNU GENERAL PUBLIC LICENSE, Version 2.0, or
|
8
|
+
# the MIT License.
|
9
|
+
#
|
10
|
+
# Refer to the COPYING.txt file distributed with this package.
|
11
|
+
#
|
12
|
+
module WurflCloud
|
13
|
+
module Helper
|
14
|
+
|
15
|
+
def wurfl_detect_device(env)
|
16
|
+
wurfl_env = WurflCloud::Environment.new(env)
|
17
|
+
wurfl_cache = WurflCloud.configuration.cache(env)
|
18
|
+
@device ||= WurflCloud::Client.detect_device(wurfl_env, wurfl_cache)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2015 ScientiaMobile Inc.
|
3
|
+
#
|
4
|
+
# The WURFL Cloud Client is intended to be used in both open-source and
|
5
|
+
# commercial environments. To allow its use in as many situations as possible,
|
6
|
+
# the WURFL Cloud Client is dual-licensed. You may choose to use the WURFL
|
7
|
+
# Cloud Client under either the GNU GENERAL PUBLIC LICENSE, Version 2.0, or
|
8
|
+
# the MIT License.
|
9
|
+
#
|
10
|
+
# Refer to the COPYING.txt file distributed with this package.
|
11
|
+
#
|
12
|
+
module WurflCloud::Rack
|
13
|
+
class CacheManager
|
14
|
+
# to be refactored: make configurable
|
15
|
+
COOKIE_NAME = 'WurflCloud_Client'
|
16
|
+
EXPIRY = 86400
|
17
|
+
|
18
|
+
def initialize(app, options={})
|
19
|
+
@app = app
|
20
|
+
end
|
21
|
+
def call(env)
|
22
|
+
# extract cookie
|
23
|
+
request = Rack::Request.new(env)
|
24
|
+
env['wurfl.cookie.device_cache'] = extract_wurfl_cookie(request.cookies)
|
25
|
+
|
26
|
+
# execute upstream request
|
27
|
+
status, headers, body = @app.call(env)
|
28
|
+
|
29
|
+
# store cookie
|
30
|
+
response = Rack::Response.new body, status, headers
|
31
|
+
response.set_cookie(COOKIE_NAME, {:value => {'date_set'=>Time.now.to_i, 'capabilities'=>env['wurfl.cookie.device_cache']}.to_json, :path => "/", :expires => Time.now+EXPIRY})
|
32
|
+
response.finish
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def extract_wurfl_cookie(cookies)
|
38
|
+
# read the cookie and try to parse it
|
39
|
+
raw_cookie = cookies[COOKIE_NAME]
|
40
|
+
parsed_cookie = JSON.parse(raw_cookie)
|
41
|
+
|
42
|
+
# if parsed then check the expiry
|
43
|
+
return nil if !parsed_cookie.has_key?('date_set') || (parsed_cookie['date_set'].to_i+EXPIRY < Time.now.to_i)
|
44
|
+
|
45
|
+
# check if the capabilities params are present
|
46
|
+
return nil if !parsed_cookie.has_key?('capabilities') || !parsed_cookie['capabilities'].is_a?(Hash) || parsed_cookie['capabilities'].empty?
|
47
|
+
|
48
|
+
parsed_cookie['capabilities']
|
49
|
+
|
50
|
+
rescue Exception=>e
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2015 ScientiaMobile Inc.
|
3
|
+
#
|
4
|
+
# The WURFL Cloud Client is intended to be used in both open-source and
|
5
|
+
# commercial environments. To allow its use in as many situations as possible,
|
6
|
+
# the WURFL Cloud Client is dual-licensed. You may choose to use the WURFL
|
7
|
+
# Cloud Client under either the GNU GENERAL PUBLIC LICENSE, Version 2.0, or
|
8
|
+
# the MIT License.
|
9
|
+
#
|
10
|
+
# Refer to the COPYING.txt file distributed with this package.
|
11
|
+
#
|
12
|
+
require 'wurfl_cloud/helper'
|
13
|
+
require 'wurfl_cloud/rack/cache_manager'
|
14
|
+
|
15
|
+
module WurflCloud
|
16
|
+
class Engine < ::Rails::Engine
|
17
|
+
|
18
|
+
# # Initialize the cache manager rack middleware
|
19
|
+
# config.app_middleware.use WurflCloud::Rack::CacheManager
|
20
|
+
|
21
|
+
# adds the moethods to the controller and views
|
22
|
+
initializer "wurf_cloud.helpers" do
|
23
|
+
ActiveSupport.on_load(:action_controller) do
|
24
|
+
include WurflCloud::Helper
|
25
|
+
helper_method :wurfl_detect_device
|
26
|
+
end
|
27
|
+
|
28
|
+
ActiveSupport.on_load(:action_view) do
|
29
|
+
include WurflCloud::Helper
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2015 ScientiaMobile Inc.
|
3
|
+
#
|
4
|
+
# The WURFL Cloud Client is intended to be used in both open-source and
|
5
|
+
# commercial environments. To allow its use in as many situations as possible,
|
6
|
+
# the WURFL Cloud Client is dual-licensed. You may choose to use the WURFL
|
7
|
+
# Cloud Client under either the GNU GENERAL PUBLIC LICENSE, Version 2.0, or
|
8
|
+
# the MIT License.
|
9
|
+
#
|
10
|
+
# Refer to the COPYING.txt file distributed with this package.
|
11
|
+
#
|
12
|
+
module WurflCloud
|
13
|
+
VERSION = "1.0.1"
|
14
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"apiVersion":"WurflCloud 1.3.2","mtime":1330016154,"id":"generic","capabilities":{"id":"generic","user_agent":"","fall_back":"root","browser_id":"browser_root","mobile_browser":"","nokia_feature_pack":0,"device_os":"","nokia_series":0,"has_qwerty_keyboard":false,"pointing_method":"mouse","mobile_browser_version":"","is_tablet":false,"nokia_edition":0,"uaprof":"","can_skip_aligned_link_row":false,"device_claims_web_support":false,"ununiqueness_handler":"","model_name":"","device_os_version":"","uaprof2":"","is_wireless_device":false,"uaprof3":"","brand_name":"generic web browser","model_extra_info":"","marketing_name":"","can_assign_phone_number":true,"release_date":"2002_january","unique":true,"icons_on_menu_items_support":false,"opwv_wml_extensions_support":false,"built_in_back_button_support":false,"proportional_font":false,"insert_br_element_after_widget_recommended":false,"wizards_recommended":false,"wml_can_display_images_and_text_on_same_line":false,"softkey_support":false,"wml_make_phone_call_string":"wtai:\/\/wp\/mc;","deck_prefetch_support":false,"menu_with_select_element_recommended":false,"numbered_menus":false,"card_title_support":true,"image_as_link_support":false,"wrap_mode_support":false,"table_support":true,"access_key_support":false,"wml_displays_image_in_center":false,"elective_forms_recommended":true,"times_square_mode_support":false,"break_list_of_links_with_br_element_recommended":true,"menu_with_list_of_links_recommended":true,"imode_region":"none","chtml_can_display_images_and_text_on_same_line":false,"chtml_displays_image_in_center":false,"chtml_make_phone_call_string":"tel:","chtml_table_support":false,"chtml_display_accesskey":false,"emoji":false,"xhtml_preferred_charset":"utf8","xhtml_supports_css_cell_table_coloring":false,"xhtml_select_as_radiobutton":false,"xhtml_autoexpand_select":false,"xhtml_avoid_accesskeys":false,"accept_third_party_cookie":true,"xhtml_make_phone_call_string":"tel:","xhtml_allows_disabled_form_elements":false,"xhtml_supports_invisible_text":false,"xhtml_select_as_dropdown":false,"cookie_support":true,"xhtml_send_mms_string":"none","xhtml_table_support":false,"xhtml_display_accesskey":false,"xhtml_can_embed_video":"none","xhtml_supports_iframe":"none","xhtmlmp_preferred_mime_type":"application\/vnd.wap.xhtml+xml","xhtml_supports_monospace_font":false,"xhtml_supports_inline_input":false,"xhtml_supports_forms_in_table":false,"xhtml_document_title_support":true,"xhtml_support_wml2_namespace":false,"xhtml_readable_background_color1":"#FFFFFF","xhtml_format_as_attribute":false,"xhtml_supports_table_for_layout":false,"xhtml_readable_background_color2":"#FFFFFF","xhtml_select_as_popup":false,"xhtml_send_sms_string":"none","xhtml_format_as_css_property":false,"xhtml_file_upload":"not_supported","xhtml_honors_bgcolor":false,"opwv_xhtml_extensions_support":false,"xhtml_marquee_as_css_property":false,"xhtml_nowrap_mode":false,"ajax_preferred_geoloc_api":"none","ajax_xhr_type":"none","ajax_support_getelementbyid":false,"ajax_support_event_listener":false,"ajax_manipulate_dom":false,"ajax_support_javascript":false,"ajax_support_inner_html":false,"ajax_manipulate_css":false,"ajax_support_events":false,"html_web_3_2":false,"html_wi_imode_htmlx_1":false,"html_wi_imode_html_1":false,"html_wi_oma_xhtmlmp_1_0":true,"html_wi_imode_html_2":false,"html_wi_w3_xhtmlbasic":true,"html_wi_imode_compact_generic":false,"html_wi_imode_html_3":false,"wml_1_1":true,"html_wi_imode_html_4":false,"wml_1_2":false,"html_wi_imode_html_5":false,"wml_1_3":false,"preferred_markup":"html_wi_oma_xhtmlmp_1_0","xhtml_support_level":1,"voicexml":false,"html_wi_imode_htmlx_1_1":false,"multipart_support":false,"html_web_4_0":false,"time_to_live_support":false,"total_cache_disable_support":false,"physical_screen_height":27,"columns":11,"dual_orientation":false,"physical_screen_width":27,"rows":6,"max_image_width":90,"resolution_height":40,"resolution_width":90,"max_image_height":35,"greyscale":false,"jpg":false,"gif":true,"transparent_png_index":false,"epoc_bmp":false,"bmp":false,"wbmp":true,"gif_animated":false,"colors":256,"svgt_1_1_plus":false,"svgt_1_1":false,"transparent_png_alpha":false,"png":false,"tiff":false,"emptyok":false,"empty_option_value_support":true,"basic_authentication_support":true,"post_method_support":true,"nokia_voice_call":false,"wta_pdc":false,"wta_voice_call":false,"wta_misc":false,"wta_phonebook":false,"phone_id_provided":false,"https_support":true,"sdio":false,"wifi":false,"has_cellular_radio":true,"max_data_rate":9,"vpn":false,"max_length_of_username":0,"max_url_length_bookmark":0,"max_no_of_bookmarks":0,"max_deck_size":4000,"max_url_length_cached_page":0,"max_length_of_password":0,"max_no_of_connection_settings":0,"max_url_length_in_requests":128,"max_object_size":0,"max_url_length_homepage":0,"video":false,"picture_bmp":false,"picture":false,"wallpaper_df_size_limit":0,"picture_preferred_width":0,"wallpaper_oma_size_limit":0,"picture_greyscale":false,"inline_support":false,"ringtone_qcelp":false,"screensaver_oma_size_limit":0,"screensaver_wbmp":false,"picture_resize":"none","picture_preferred_height":0,"ringtone_rmf":false,"wallpaper_wbmp":false,"wallpaper_jpg":false,"screensaver_bmp":false,"screensaver_max_width":0,"picture_inline_size_limit":0,"picture_colors":2,"ringtone_midi_polyphonic":false,"ringtone_midi_monophonic":false,"screensaver_preferred_height":0,"ringtone_voices":1,"ringtone_3gpp":false,"oma_support":false,"ringtone_inline_size_limit":0,"wallpaper_preferred_width":0,"wallpaper_greyscale":false,"screensaver_preferred_width":0,"wallpaper_preferred_height":0,"picture_max_width":0,"picture_jpg":false,"ringtone_aac":false,"ringtone_oma_size_limit":0,"wallpaper_directdownload_size_limit":0,"screensaver_inline_size_limit":0,"ringtone_xmf":false,"picture_max_height":0,"screensaver_max_height":0,"ringtone_mp3":false,"wallpaper_png":false,"screensaver_jpg":false,"ringtone_directdownload_size_limit":0,"wallpaper_max_width":0,"wallpaper_max_height":0,"screensaver":false,"ringtone_wav":false,"wallpaper_gif":false,"screensaver_directdownload_size_limit":0,"picture_df_size_limit":0,"wallpaper_tiff":false,"screensaver_df_size_limit":0,"ringtone_awb":false,"ringtone":false,"wallpaper_inline_size_limit":0,"picture_directdownload_size_limit":0,"picture_png":false,"wallpaper_bmp":false,"picture_wbmp":false,"ringtone_df_size_limit":0,"picture_oma_size_limit":0,"picture_gif":false,"screensaver_png":false,"wallpaper_resize":"none","screensaver_greyscale":false,"ringtone_mmf":false,"ringtone_amr":false,"wallpaper":false,"ringtone_digiplug":false,"ringtone_spmidi":false,"ringtone_compactmidi":false,"ringtone_imelody":false,"screensaver_resize":"none","wallpaper_colors":2,"directdownload_support":false,"downloadfun_support":false,"screensaver_colors":2,"screensaver_gif":false,"oma_v_1_0_combined_delivery":false,"oma_v_1_0_separate_delivery":false,"oma_v_1_0_forwardlock":false,"streaming_vcodec_mpeg4_asp":-1,"streaming_video_size_limit":0,"streaming_mov":false,"streaming_wmv":"none","streaming_acodec_aac":"none","streaming_vcodec_h263_0":-1,"streaming_real_media":"none","streaming_3g2":false,"streaming_3gpp":false,"streaming_acodec_amr":"none","streaming_vcodec_h264_bp":-1,"streaming_vcodec_h263_3":-1,"streaming_preferred_protocol":"rtsp","streaming_vcodec_mpeg4_sp":-1,"streaming_flv":false,"streaming_video":false,"streaming_preferred_http_protocol":"none","streaming_mp4":false,"expiration_date":false,"utf8_support":false,"connectionless_cache_operation":false,"connectionless_service_load":false,"iso8859_support":false,"connectionoriented_confirmed_service_indication":false,"connectionless_service_indication":false,"ascii_support":false,"connectionoriented_confirmed_cache_operation":false,"connectionoriented_confirmed_service_load":false,"wap_push_support":false,"connectionoriented_unconfirmed_cache_operation":false,"connectionoriented_unconfirmed_service_load":false,"connectionoriented_unconfirmed_service_indication":false,"doja_1_5":false,"j2me_datefield_broken":false,"j2me_clear_key_code":0,"j2me_right_softkey_code":0,"j2me_heap_size":0,"j2me_canvas_width":0,"j2me_motorola_lwt":false,"doja_3_5":false,"j2me_wbmp":false,"j2me_rmf":false,"j2me_wma":false,"j2me_left_softkey_code":0,"j2me_jtwi":false,"j2me_jpg":false,"j2me_return_key_code":0,"j2me_real8":false,"j2me_max_record_store_size":0,"j2me_realmedia":false,"j2me_midp_1_0":false,"j2me_bmp3":false,"j2me_midi":false,"j2me_btapi":false,"j2me_locapi":false,"j2me_siemens_extension":false,"j2me_h263":false,"j2me_audio_capture_enabled":false,"j2me_midp_2_0":false,"j2me_datefield_no_accepts_null_date":false,"j2me_aac":false,"j2me_capture_image_formats":"none","j2me_select_key_code":0,"j2me_xmf":false,"j2me_photo_capture_enabled":false,"j2me_realaudio":false,"j2me_realvideo":false,"j2me_mp3":false,"j2me_png":false,"j2me_au":false,"j2me_screen_width":0,"j2me_mp4":false,"j2me_mmapi_1_0":false,"j2me_http":false,"j2me_imelody":false,"j2me_socket":false,"j2me_3dapi":false,"j2me_bits_per_pixel":0,"j2me_mmapi_1_1":false,"j2me_udp":false,"j2me_wav":false,"j2me_middle_softkey_code":0,"j2me_svgt":false,"j2me_gif":false,"j2me_siemens_color_game":false,"j2me_max_jar_size":0,"j2me_wmapi_1_0":false,"j2me_nokia_ui":false,"j2me_screen_height":0,"j2me_wmapi_1_1":false,"j2me_wmapi_2_0":false,"doja_1_0":false,"j2me_serial":false,"doja_2_0":false,"j2me_bmp":false,"j2me_amr":false,"j2me_gif89a":false,"j2me_cldc_1_0":false,"doja_2_1":false,"doja_3_0":false,"j2me_cldc_1_1":false,"doja_2_2":false,"doja_4_0":false,"j2me_3gpp":false,"j2me_video_capture_enabled":false,"j2me_canvas_height":0,"j2me_https":false,"j2me_mpeg4":false,"j2me_storage_size":0,"mms_3gpp":false,"mms_wbxml":false,"mms_symbian_install":false,"mms_png":false,"mms_max_size":0,"mms_rmf":false,"mms_nokia_operatorlogo":false,"mms_max_width":0,"mms_max_frame_rate":0,"mms_wml":false,"mms_evrc":false,"mms_spmidi":false,"mms_gif_static":false,"mms_max_height":0,"sender":false,"mms_video":false,"mms_vcard":false,"mms_nokia_3dscreensaver":false,"mms_qcelp":false,"mms_midi_polyphonic":false,"mms_wav":false,"mms_jpeg_progressive":false,"mms_jad":false,"mms_nokia_ringingtone":false,"built_in_recorder":false,"mms_midi_monophonic":false,"mms_3gpp2":false,"mms_wmlc":false,"mms_nokia_wallpaper":false,"mms_bmp":false,"mms_vcalendar":false,"mms_jar":false,"mms_ota_bitmap":false,"mms_mp3":false,"mms_mmf":false,"mms_amr":false,"mms_wbmp":false,"built_in_camera":false,"receiver":false,"mms_mp4":false,"mms_xmf":false,"mms_jpeg_baseline":false,"mms_midi_polyphonic_voices":0,"mms_gif_animated":false,"ems":false,"text_imelody":false,"nokiaring":false,"siemens_logo_height":29,"ems_variablesizedpictures":false,"sckl_groupgraphic":false,"siemens_ota":false,"sagem_v1":false,"largeoperatorlogo":false,"sagem_v2":false,"ems_version":0,"ems_odi":false,"nokiavcal":false,"operatorlogo":false,"siemens_logo_width":101,"ems_imelody":false,"sckl_vcard":false,"siemens_screensaver_width":101,"sckl_operatorlogo":false,"panasonic":false,"ems_upi":false,"nokiavcard":false,"callericon":false,"sms_enabled":true,"gprtf":false,"siemens_screensaver_height":50,"sckl_ringtone":false,"picturemessage":false,"sckl_vcalendar":false,"rmf":false,"qcelp":false,"awb":false,"smf":false,"wav":false,"nokia_ringtone":false,"aac":false,"digiplug":false,"sp_midi":false,"compactmidi":false,"voices":1,"mp3":false,"mld":false,"evrc":false,"amr":false,"xmf":false,"mmf":false,"imelody":false,"midi_monophonic":false,"au":false,"midi_polyphonic":false,"flash_lite_version":"","fl_wallpaper":false,"fl_browser":false,"fl_screensaver":false,"fl_standalone":false,"full_flash_support":false,"fl_sub_lcd":false,"css_gradient":"none","css_border_image":"none","css_rounded_corners":"none","css_spriting":false,"css_supports_width_as_percentage":true,"is_transcoder":false,"transcoder_ua_header":"user-agent","rss_support":false,"pdf_support":false,"playback_oma_size_limit":0,"playback_acodec_aac":"none","playback_vcodec_h263_3":-1,"playback_vcodec_mpeg4_asp":-1,"playback_mp4":false,"playback_3gpp":false,"playback_df_size_limit":0,"playback_acodec_amr":"none","playback_mov":false,"playback_wmv":"none","playback_acodec_qcelp":false,"progressive_download":false,"playback_directdownload_size_limit":0,"playback_real_media":"none","playback_3g2":false,"playback_vcodec_mpeg4_sp":-1,"playback_vcodec_h263_0":-1,"playback_inline_size_limit":0,"hinted_progressive_download":false,"playback_vcodec_h264_bp":-1,"streaming_video_acodec_amr":false,"streaming_video_vcodec_h263_0":false,"streaming_video_max_video_bit_rate":0,"video_acodec_amr":false,"video_vcodec_h263_3":false,"video_directdownload_size_limit":0,"video_max_width":0,"streaming_video_sqcif":false,"streaming_real_media_10":false,"has_pointing_device":false,"streaming_video_sqcif_max_width":0,"video_vcodec_mpeg4":false,"video_inline_size_limit":0,"streaming_video_vcodec_h263_3":false,"streaming_video_max_bit_rate":0,"video_vcodec_h264":"none","streaming_video_sqcif_max_height":0,"video_df_size_limit":0,"video_3gpp2":false,"video_real_media_8":false,"streaming_video_max_audio_bit_rate":0,"video_real_media_10":false,"video_real_media_9":false,"xhtml_supports_file_upload":false,"streaming_video_vcodec_mpeg4":false,"video_acodec_qcelp":false,"video_acodec_awb":false,"video_max_height":0,"video_mp4":false,"video_3gpp":false,"streaming_video_acodec_aac_ltp":false,"streaming_video_acodec_awb":false,"streaming_video_max_frame_rate":0,"streaming_real_media_8":false,"video_acodec_aac":false,"video_oma_size_limit":0,"streaming_video_acodec_aac":false,"streaming_video_min_video_bit_rate":0,"streaming_real_media_9":false,"video_vcodec_h263_0":false,"video_preferred_width":0,"video_sqcif":false,"video_qcif":false,"streaming_video_qcif":false,"video_preferred_height":0,"video_mov":false,"streaming_prefered_http_protocol":"none","streaming_video_vcodec_h264":"none","streaming_video_qcif_max_height":0,"streaming_video_qcif_max_width":0,"video_acodec_aac_ltp":false,"video_max_frame_rate":0,"video_wmv":false,"https_detectable":false,"canvas_support":"none","viewport_width":"","html_preferred_dtd":"html4","viewport_supported":false,"viewport_minimum_scale":"","viewport_initial_scale":"","mobileoptimized":false,"viewport_maximum_scale":"","viewport_userscalable":"","image_inlining":false,"handheldfriendly":false,"is_smarttv":false,"fm_tuner_support":false,"nfc_support":false,"ux_full_desktop":false,"ux_full_web_usability_index":-100,"num_queries":3,"match_type":"none","matcher":"none","match":false,"lookup_time":0.0031659603118896,"matcher_history":"CatchAllUserAgentMatcher(exact),CatchAllUserAgentMatcher(conclusive),CatchAllUserAgentMatcher(recovery),http_accept","actual_root_device":"","fall_back_tree":"generic"},"errors":{}}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"apiVersion":"WurflCloud 1.3.2","mtime":1330016154,"id":"generic","capabilities":{"is_wireless_device":false,"browser_id":"browser_root","fall_back":"root","user_agent":"","resolution_width": 800,"device_os_version":10.5},"errors":{}}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"apiVersion":"WurflCloud 1.3.2","mtime":1330016154,"id":"nokia_lumia_800_ver1","capabilities":{"id":"nokia_lumia_800_ver1","user_agent":"Mozilla\/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident\/5.0; IEMobile\/9.0; NOKIA; Lumia 800)","fall_back":"generic_ms_nokia_phone_os7_5","actual_device_root":1,"browser_id":"browser_winmo_iemobile9","mobile_browser":"IEMobile","nokia_feature_pack":0,"device_os":"Windows Phone OS","nokia_series":0,"has_qwerty_keyboard":true,"pointing_method":"touchscreen","mobile_browser_version":"9.0","is_tablet":false,"nokia_edition":0,"uaprof":"http:\/\/nds1.nds.nokia.com\/uaprof\/Nokia800r100.xml","can_skip_aligned_link_row":true,"device_claims_web_support":true,"ununiqueness_handler":"","model_name":"Lumia 800","device_os_version":7.5,"uaprof2":"","is_wireless_device":true,"uaprof3":"","brand_name":"Nokia","model_extra_info":"","marketing_name":"","can_assign_phone_number":true,"release_date":"2011_october","unique":true,"icons_on_menu_items_support":false,"opwv_wml_extensions_support":false,"built_in_back_button_support":false,"proportional_font":false,"insert_br_element_after_widget_recommended":false,"wizards_recommended":false,"wml_can_display_images_and_text_on_same_line":false,"softkey_support":false,"wml_make_phone_call_string":"wtai:\/\/wp\/mc;","deck_prefetch_support":false,"menu_with_select_element_recommended":false,"numbered_menus":false,"card_title_support":true,"image_as_link_support":false,"wrap_mode_support":false,"table_support":true,"access_key_support":false,"wml_displays_image_in_center":false,"elective_forms_recommended":true,"times_square_mode_support":false,"break_list_of_links_with_br_element_recommended":true,"menu_with_list_of_links_recommended":true,"imode_region":"none","chtml_can_display_images_and_text_on_same_line":false,"chtml_displays_image_in_center":false,"chtml_make_phone_call_string":"tel:","chtml_table_support":false,"chtml_display_accesskey":false,"emoji":false,"xhtml_preferred_charset":"utf8","xhtml_supports_css_cell_table_coloring":false,"xhtml_select_as_radiobutton":false,"xhtml_autoexpand_select":false,"xhtml_avoid_accesskeys":false,"accept_third_party_cookie":true,"xhtml_make_phone_call_string":"tel:","xhtml_allows_disabled_form_elements":false,"xhtml_supports_invisible_text":false,"xhtml_select_as_dropdown":false,"cookie_support":true,"xhtml_send_mms_string":"none","xhtml_table_support":true,"xhtml_display_accesskey":false,"xhtml_can_embed_video":"none","xhtml_supports_iframe":"full","xhtmlmp_preferred_mime_type":"application\/vnd.wap.xhtml+xml","xhtml_supports_monospace_font":false,"xhtml_supports_inline_input":false,"xhtml_supports_forms_in_table":false,"xhtml_document_title_support":true,"xhtml_support_wml2_namespace":false,"xhtml_readable_background_color1":"#FFFFFF","xhtml_format_as_attribute":false,"xhtml_supports_table_for_layout":false,"xhtml_readable_background_color2":"#FFFFFF","xhtml_select_as_popup":false,"xhtml_send_sms_string":"none","xhtml_format_as_css_property":false,"xhtml_file_upload":"not_supported","xhtml_honors_bgcolor":false,"opwv_xhtml_extensions_support":false,"xhtml_marquee_as_css_property":false,"xhtml_nowrap_mode":false,"ajax_preferred_geoloc_api":"none","ajax_xhr_type":"standard","ajax_support_getelementbyid":true,"ajax_support_event_listener":true,"ajax_manipulate_dom":true,"ajax_support_javascript":true,"ajax_support_inner_html":true,"ajax_manipulate_css":true,"ajax_support_events":true,"html_web_3_2":false,"html_wi_imode_htmlx_1":false,"html_wi_imode_html_1":false,"html_wi_oma_xhtmlmp_1_0":true,"html_wi_imode_html_2":false,"html_wi_w3_xhtmlbasic":true,"html_wi_imode_compact_generic":false,"html_wi_imode_html_3":false,"wml_1_1":false,"html_wi_imode_html_4":false,"wml_1_2":false,"html_wi_imode_html_5":false,"wml_1_3":false,"preferred_markup":"html_web_4_0","xhtml_support_level":4,"voicexml":false,"html_wi_imode_htmlx_1_1":false,"multipart_support":false,"html_web_4_0":true,"time_to_live_support":false,"total_cache_disable_support":false,"physical_screen_height":161,"columns":16,"dual_orientation":true,"physical_screen_width":97,"rows":12,"max_image_width":320,"resolution_height":800,"resolution_width":480,"max_image_height":480,"greyscale":false,"jpg":true,"gif":true,"transparent_png_index":false,"epoc_bmp":false,"bmp":false,"wbmp":false,"gif_animated":true,"colors":65536,"svgt_1_1_plus":false,"svgt_1_1":false,"transparent_png_alpha":false,"png":true,"tiff":false,"emptyok":false,"empty_option_value_support":true,"basic_authentication_support":true,"post_method_support":true,"nokia_voice_call":false,"wta_pdc":false,"wta_voice_call":false,"wta_misc":false,"wta_phonebook":false,"phone_id_provided":false,"https_support":true,"sdio":false,"wifi":true,"has_cellular_radio":true,"max_data_rate":384,"vpn":false,"max_length_of_username":0,"max_url_length_bookmark":0,"max_no_of_bookmarks":0,"max_deck_size":100000,"max_url_length_cached_page":0,"max_length_of_password":0,"max_no_of_connection_settings":0,"max_url_length_in_requests":512,"max_object_size":0,"max_url_length_homepage":0,"video":false,"picture_bmp":false,"picture":false,"wallpaper_df_size_limit":0,"picture_preferred_width":0,"wallpaper_oma_size_limit":0,"picture_greyscale":false,"inline_support":false,"ringtone_qcelp":false,"screensaver_oma_size_limit":0,"screensaver_wbmp":false,"picture_resize":"none","picture_preferred_height":0,"ringtone_rmf":false,"wallpaper_wbmp":false,"wallpaper_jpg":false,"screensaver_bmp":false,"screensaver_max_width":0,"picture_inline_size_limit":0,"picture_colors":2,"ringtone_midi_polyphonic":false,"ringtone_midi_monophonic":false,"screensaver_preferred_height":0,"ringtone_voices":1,"ringtone_3gpp":false,"oma_support":false,"ringtone_inline_size_limit":0,"wallpaper_preferred_width":0,"wallpaper_greyscale":false,"screensaver_preferred_width":0,"wallpaper_preferred_height":0,"picture_max_width":0,"picture_jpg":false,"ringtone_aac":false,"ringtone_oma_size_limit":0,"wallpaper_directdownload_size_limit":0,"screensaver_inline_size_limit":0,"ringtone_xmf":false,"picture_max_height":0,"screensaver_max_height":0,"ringtone_mp3":false,"wallpaper_png":false,"screensaver_jpg":false,"ringtone_directdownload_size_limit":0,"wallpaper_max_width":0,"wallpaper_max_height":0,"screensaver":false,"ringtone_wav":false,"wallpaper_gif":false,"screensaver_directdownload_size_limit":0,"picture_df_size_limit":0,"wallpaper_tiff":false,"screensaver_df_size_limit":0,"ringtone_awb":false,"ringtone":false,"wallpaper_inline_size_limit":0,"picture_directdownload_size_limit":0,"picture_png":false,"wallpaper_bmp":false,"picture_wbmp":false,"ringtone_df_size_limit":0,"picture_oma_size_limit":0,"picture_gif":false,"screensaver_png":false,"wallpaper_resize":"none","screensaver_greyscale":false,"ringtone_mmf":false,"ringtone_amr":false,"wallpaper":false,"ringtone_digiplug":false,"ringtone_spmidi":false,"ringtone_compactmidi":false,"ringtone_imelody":false,"screensaver_resize":"none","wallpaper_colors":2,"directdownload_support":false,"downloadfun_support":false,"screensaver_colors":2,"screensaver_gif":false,"oma_v_1_0_combined_delivery":false,"oma_v_1_0_separate_delivery":false,"oma_v_1_0_forwardlock":false,"streaming_vcodec_mpeg4_asp":-1,"streaming_video_size_limit":0,"streaming_mov":false,"streaming_wmv":9,"streaming_acodec_aac":"lc","streaming_vcodec_h263_0":10,"streaming_real_media":"none","streaming_3g2":true,"streaming_3gpp":true,"streaming_acodec_amr":"nb","streaming_vcodec_h264_bp":0,"streaming_vcodec_h263_3":-1,"streaming_preferred_protocol":"http","streaming_vcodec_mpeg4_sp":0,"streaming_flv":false,"streaming_video":true,"streaming_preferred_http_protocol":"microsoft_smooth_streaming","streaming_mp4":true,"expiration_date":false,"utf8_support":false,"connectionless_cache_operation":false,"connectionless_service_load":true,"iso8859_support":false,"connectionoriented_confirmed_service_indication":false,"connectionless_service_indication":true,"ascii_support":false,"connectionoriented_confirmed_cache_operation":false,"connectionoriented_confirmed_service_load":false,"wap_push_support":true,"connectionoriented_unconfirmed_cache_operation":false,"connectionoriented_unconfirmed_service_load":false,"connectionoriented_unconfirmed_service_indication":false,"doja_1_5":false,"j2me_datefield_broken":false,"j2me_clear_key_code":0,"j2me_right_softkey_code":0,"j2me_heap_size":0,"j2me_canvas_width":0,"j2me_motorola_lwt":false,"doja_3_5":false,"j2me_wbmp":false,"j2me_rmf":false,"j2me_wma":false,"j2me_left_softkey_code":0,"j2me_jtwi":false,"j2me_jpg":false,"j2me_return_key_code":0,"j2me_real8":false,"j2me_max_record_store_size":0,"j2me_realmedia":false,"j2me_midp_1_0":false,"j2me_bmp3":false,"j2me_midi":false,"j2me_btapi":false,"j2me_locapi":false,"j2me_siemens_extension":false,"j2me_h263":false,"j2me_audio_capture_enabled":false,"j2me_midp_2_0":false,"j2me_datefield_no_accepts_null_date":false,"j2me_aac":false,"j2me_capture_image_formats":"none","j2me_select_key_code":0,"j2me_xmf":false,"j2me_photo_capture_enabled":false,"j2me_realaudio":false,"j2me_realvideo":false,"j2me_mp3":false,"j2me_png":false,"j2me_au":false,"j2me_screen_width":0,"j2me_mp4":false,"j2me_mmapi_1_0":false,"j2me_http":false,"j2me_imelody":false,"j2me_socket":false,"j2me_3dapi":false,"j2me_bits_per_pixel":0,"j2me_mmapi_1_1":false,"j2me_udp":false,"j2me_wav":false,"j2me_middle_softkey_code":0,"j2me_svgt":false,"j2me_gif":false,"j2me_siemens_color_game":false,"j2me_max_jar_size":0,"j2me_wmapi_1_0":false,"j2me_nokia_ui":false,"j2me_screen_height":0,"j2me_wmapi_1_1":false,"j2me_wmapi_2_0":false,"doja_1_0":false,"j2me_serial":false,"doja_2_0":false,"j2me_bmp":false,"j2me_amr":false,"j2me_gif89a":false,"j2me_cldc_1_0":false,"doja_2_1":false,"doja_3_0":false,"j2me_cldc_1_1":false,"doja_2_2":false,"doja_4_0":false,"j2me_3gpp":false,"j2me_video_capture_enabled":false,"j2me_canvas_height":0,"j2me_https":false,"j2me_mpeg4":false,"j2me_storage_size":0,"mms_3gpp":true,"mms_wbxml":false,"mms_symbian_install":false,"mms_png":true,"mms_max_size":614400,"mms_rmf":false,"mms_nokia_operatorlogo":false,"mms_max_width":1600,"mms_max_frame_rate":0,"mms_wml":false,"mms_evrc":false,"mms_spmidi":false,"mms_gif_static":true,"mms_max_height":1600,"sender":true,"mms_video":true,"mms_vcard":false,"mms_nokia_3dscreensaver":false,"mms_qcelp":false,"mms_midi_polyphonic":false,"mms_wav":true,"mms_jpeg_progressive":false,"mms_jad":false,"mms_nokia_ringingtone":false,"built_in_recorder":false,"mms_midi_monophonic":false,"mms_3gpp2":true,"mms_wmlc":false,"mms_nokia_wallpaper":false,"mms_bmp":true,"mms_vcalendar":false,"mms_jar":false,"mms_ota_bitmap":false,"mms_mp3":true,"mms_mmf":false,"mms_amr":false,"mms_wbmp":false,"built_in_camera":false,"receiver":true,"mms_mp4":true,"mms_xmf":false,"mms_jpeg_baseline":true,"mms_midi_polyphonic_voices":0,"mms_gif_animated":true,"ems":false,"text_imelody":false,"nokiaring":false,"siemens_logo_height":29,"ems_variablesizedpictures":false,"sckl_groupgraphic":false,"siemens_ota":false,"sagem_v1":false,"largeoperatorlogo":false,"sagem_v2":false,"ems_version":0,"ems_odi":false,"nokiavcal":false,"operatorlogo":false,"siemens_logo_width":101,"ems_imelody":false,"sckl_vcard":false,"siemens_screensaver_width":101,"sckl_operatorlogo":false,"panasonic":false,"ems_upi":false,"nokiavcard":false,"callericon":false,"sms_enabled":true,"gprtf":false,"siemens_screensaver_height":50,"sckl_ringtone":false,"picturemessage":false,"sckl_vcalendar":false,"rmf":false,"qcelp":false,"awb":false,"smf":false,"wav":true,"nokia_ringtone":false,"aac":true,"digiplug":false,"sp_midi":false,"compactmidi":false,"voices":1,"mp3":true,"mld":false,"evrc":false,"amr":false,"xmf":false,"mmf":false,"imelody":false,"midi_monophonic":false,"au":false,"midi_polyphonic":false,"flash_lite_version":"","fl_wallpaper":false,"fl_browser":false,"fl_screensaver":false,"fl_standalone":false,"full_flash_support":false,"fl_sub_lcd":false,"css_gradient":"none","css_border_image":"none","css_rounded_corners":"none","css_spriting":true,"css_supports_width_as_percentage":true,"is_transcoder":false,"transcoder_ua_header":"user-agent","rss_support":true,"pdf_support":true,"playback_oma_size_limit":0,"playback_acodec_aac":"lc","playback_vcodec_h263_3":-1,"playback_vcodec_mpeg4_asp":-1,"playback_mp4":true,"playback_3gpp":true,"playback_df_size_limit":0,"playback_acodec_amr":"nb","playback_mov":false,"playback_wmv":9,"playback_acodec_qcelp":false,"progressive_download":true,"playback_directdownload_size_limit":0,"playback_real_media":"none","playback_3g2":true,"playback_vcodec_mpeg4_sp":0,"playback_vcodec_h263_0":10,"playback_inline_size_limit":0,"hinted_progressive_download":false,"playback_vcodec_h264_bp":0,"streaming_video_acodec_amr":false,"streaming_video_vcodec_h263_0":false,"streaming_video_max_video_bit_rate":0,"video_acodec_amr":false,"video_vcodec_h263_3":false,"video_directdownload_size_limit":0,"video_max_width":0,"streaming_video_sqcif":false,"streaming_real_media_10":false,"has_pointing_device":false,"streaming_video_sqcif_max_width":0,"video_vcodec_mpeg4":false,"video_inline_size_limit":0,"streaming_video_vcodec_h263_3":false,"streaming_video_max_bit_rate":0,"video_vcodec_h264":"none","streaming_video_sqcif_max_height":0,"video_df_size_limit":0,"video_3gpp2":false,"video_real_media_8":false,"streaming_video_max_audio_bit_rate":0,"video_real_media_10":false,"video_real_media_9":false,"xhtml_supports_file_upload":false,"streaming_video_vcodec_mpeg4":false,"video_acodec_qcelp":false,"video_acodec_awb":false,"video_max_height":0,"video_mp4":false,"video_3gpp":false,"streaming_video_acodec_aac_ltp":false,"streaming_video_acodec_awb":false,"streaming_video_max_frame_rate":0,"streaming_real_media_8":false,"video_acodec_aac":false,"video_oma_size_limit":0,"streaming_video_acodec_aac":false,"streaming_video_min_video_bit_rate":0,"streaming_real_media_9":false,"video_vcodec_h263_0":false,"video_preferred_width":0,"video_sqcif":false,"video_qcif":false,"streaming_video_qcif":false,"video_preferred_height":0,"video_mov":false,"streaming_prefered_http_protocol":"microsoft_smooth_streaming","streaming_video_vcodec_h264":"none","streaming_video_qcif_max_height":0,"streaming_video_qcif_max_width":0,"video_acodec_aac_ltp":false,"video_max_frame_rate":0,"video_wmv":false,"https_detectable":false,"canvas_support":"none","viewport_width":"device_width_token","html_preferred_dtd":"html4","viewport_supported":true,"viewport_minimum_scale":"","viewport_initial_scale":"","mobileoptimized":false,"viewport_maximum_scale":"","viewport_userscalable":"no","image_inlining":true,"handheldfriendly":false,"is_smarttv":false,"fm_tuner_support":false,"nfc_support":false,"ux_full_desktop":false,"ux_full_web_usability_index":-50,"num_queries":2,"match_type":"exact","matcher":"WindowsPhoneUserAgentMatcher","match":true,"lookup_time":0.0045168399810791,"matcher_history":"WindowsPhoneUserAgentMatcher(exact)","actual_root_device":"nokia_lumia_800_ver1","fall_back_tree":"nokia_lumia_800_ver1,generic_ms_nokia_phone_os7_5,generic_ms_phone_os7_5,generic_ms_phone_os7,generic_xhtml,generic_mobile,generic"},"errors":{}}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"apiVersion":"WurflCloud 1.3.2","mtime":1330016154,"id":"nokia_lumia_800_ver1","capabilities":{"is_wireless_device":true,"browser_id":"browser_winmo_iemobile9","fall_back":"generic_ms_nokia_phone_os7_5","user_agent":"Mozilla\/5.0 (compatible; MSIE 9.0; Windows Phone OS 7.5; Trident\/5.0; IEMobile\/9.0; NOKIA; Lumia 800)"},"errors":{}}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"apiVersion":"WurflCloud 1.3.2","mtime":1330016154,"id":"generic","capabilities":{"release_date": "1994_january","is_wireless_device":"true","is_tablet":"false","resolution_width": "800"},"errors":{}}
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2015 ScientiaMobile Inc.
|
3
|
+
#
|
4
|
+
# The WURFL Cloud Client is intended to be used in both open-source and
|
5
|
+
# commercial environments. To allow its use in as many situations as possible,
|
6
|
+
# the WURFL Cloud Client is dual-licensed. You may choose to use the WURFL
|
7
|
+
# Cloud Client under either the GNU GENERAL PUBLIC LICENSE, Version 2.0, or
|
8
|
+
# the MIT License.
|
9
|
+
#
|
10
|
+
# Refer to the COPYING.txt file distributed with this package.
|
11
|
+
#
|
12
|
+
require 'simplecov'
|
13
|
+
SimpleCov.start do
|
14
|
+
add_filter "/spec/"
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
require 'wurfl_cloud'
|
19
|
+
require 'webmock/rspec'
|
20
|
+
require 'rack'
|
21
|
+
|
22
|
+
# Load support files
|
23
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
24
|
+
|
25
|
+
RSpec.configure do |config|
|
26
|
+
config.include(WurflCloud::Spec::RackHelpers)
|
27
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# adapted from warden
|
3
|
+
#
|
4
|
+
# Copyright (c) 2009 Daniel Neighman
|
5
|
+
#
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
# a copy of this software and associated documentation files (the
|
8
|
+
# "Software"), to deal in the Software without restriction, including
|
9
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
# the following conditions:
|
13
|
+
#
|
14
|
+
# The above copyright notice and this permission notice shall be
|
15
|
+
# included in all copies or substantial portions of the Software.
|
16
|
+
#
|
17
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
20
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
21
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
22
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
23
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
24
|
+
#
|
25
|
+
require 'wurfl_cloud/rack/cache_manager'
|
26
|
+
|
27
|
+
module WurflCloud::Spec
|
28
|
+
module RackHelpers
|
29
|
+
FAILURE_APP = lambda{|e|[401, {"Content-Type" => "text/plain"}, ["You Fail!"]] }
|
30
|
+
|
31
|
+
def env_with_params(path = "/", params = {}, env = {})
|
32
|
+
method = params.delete(:method) || "GET"
|
33
|
+
env = { 'HTTP_VERSION' => '1.1', 'REQUEST_METHOD' => "#{method}" }.merge(env)
|
34
|
+
Rack::MockRequest.env_for("#{path}?#{Rack::Utils.build_query(params)}", env)
|
35
|
+
end
|
36
|
+
|
37
|
+
def setup_rack(app = nil, opts = {}, &block)
|
38
|
+
app ||= block if block_given?
|
39
|
+
|
40
|
+
opts[:failure_app] ||= failure_app
|
41
|
+
|
42
|
+
Rack::Builder.new do
|
43
|
+
use opts[:session] || WurflCloud::Spec::RackHelpers::Session
|
44
|
+
use WurflCloud::Rack::CacheManager, opts
|
45
|
+
run app
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def valid_response
|
50
|
+
Rack::Response.new("OK").finish
|
51
|
+
end
|
52
|
+
|
53
|
+
def failure_app
|
54
|
+
WurflCloud::Spec::RackHelpers::FAILURE_APP
|
55
|
+
end
|
56
|
+
|
57
|
+
def success_app
|
58
|
+
lambda{|e| [200, {"Content-Type" => "text/plain"}, ["You Win"]]}
|
59
|
+
end
|
60
|
+
|
61
|
+
class Session
|
62
|
+
attr_accessor :app
|
63
|
+
def initialize(app,configs = {})
|
64
|
+
@app = app
|
65
|
+
end
|
66
|
+
|
67
|
+
def call(e)
|
68
|
+
e['rack.session'] ||= {}
|
69
|
+
@app.call(e)
|
70
|
+
end
|
71
|
+
end # session
|
72
|
+
|
73
|
+
|
74
|
+
def authenticated_uri
|
75
|
+
c = WurflCloud.configuration
|
76
|
+
"#{c.schema}://#{c.api_user}:#{c.api_password}@#{c.host}:#{c.port}#{c.path}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|