wurfl_cloud_client 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +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
|