wurfl_cloud_client 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +5 -0
  3. data/Gemfile +4 -0
  4. data/Gemfile.lock +40 -0
  5. data/Rakefile +19 -0
  6. data/lib/wurfl_cloud.rb +49 -0
  7. data/lib/wurfl_cloud/cache/cookie.rb +43 -0
  8. data/lib/wurfl_cloud/cache/local_memory.rb +43 -0
  9. data/lib/wurfl_cloud/cache/memcached.rb +64 -0
  10. data/lib/wurfl_cloud/cache/null.rb +41 -0
  11. data/lib/wurfl_cloud/cache/rails.rb +56 -0
  12. data/lib/wurfl_cloud/client.rb +105 -0
  13. data/lib/wurfl_cloud/configuration.rb +88 -0
  14. data/lib/wurfl_cloud/device_capabilities.rb +78 -0
  15. data/lib/wurfl_cloud/environment.rb +48 -0
  16. data/lib/wurfl_cloud/errors.rb +23 -0
  17. data/lib/wurfl_cloud/helper.rb +21 -0
  18. data/lib/wurfl_cloud/rack/cache_manager.rb +54 -0
  19. data/lib/wurfl_cloud/rails.rb +34 -0
  20. data/lib/wurfl_cloud/version.rb +14 -0
  21. data/spec/files/generic.json +1 -0
  22. data/spec/files/generic_filtered.json +1 -0
  23. data/spec/files/lumia.json +1 -0
  24. data/spec/files/lumia_filtered.json +1 -0
  25. data/spec/files/strange_values.json +1 -0
  26. data/spec/spec_helper.rb +27 -0
  27. data/spec/support/rack_helpers.rb +79 -0
  28. data/spec/support/string_extensions.rb +33 -0
  29. data/spec/wurfl_cloud/client_spec.rb +207 -0
  30. data/spec/wurfl_cloud/configuration_spec.rb +118 -0
  31. data/spec/wurfl_cloud/cookie_cache_spec.rb +51 -0
  32. data/spec/wurfl_cloud/device_capabilities_spec.rb +143 -0
  33. data/spec/wurfl_cloud/environment_spec.rb +93 -0
  34. data/spec/wurfl_cloud/helper_spec.rb +35 -0
  35. data/spec/wurfl_cloud/memcached_cache_spec.rb +122 -0
  36. data/spec/wurfl_cloud/null_cache_spec.rb +37 -0
  37. data/spec/wurfl_cloud/rack_cache_manager_spec.rb +76 -0
  38. data/spec/wurfl_cloud/rails_cache_spec.rb +126 -0
  39. data/spec/wurfl_cloud/server_request_spec.rb +45 -0
  40. data/wurfl_cloud_client.gemspec +38 -0
  41. 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":{}}
@@ -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