Copyright © 2014 by mTLD Top Level Domain Limited. All rights reserved.
Portions copyright © 2008 by Argo Interactive Limited.
Portions copyright © 2008 by Nokia Inc.
Portions copyright © 2008 by Telecom Italia Mobile S.p.A.
Portions copyright © 2008 by Volantis Systems Limited.
Portions copyright © 2002-2008 by Andreas Staeding.
Portions copyright © 2008 by Zandan.
dotMobi
tree key - has children
tree key - list of compiled regexes
tree key - property data
device-id property name
tree key - user-agent header names {“h”:{“sl”:}}
tree key - tree main branch
tree key - masked properties
tree key - {DATA-META-DATA}
tree key - tree revision
tree key - tree create time-stamp
tree key - tree structure version
tree key - property names [property-name,]
tree key - list of regexes [regex(String),]
tree key - stock user-agent header names {“h”:{“sl”:}}
tree key - property values [property-value,]
for MAP optimization, set to average number properties
A list of http-headers which may contain the original user-agent. if the tree does not contain KEY_UA_STOCK_HEADERS then this list will be used
Load the JSON tree into a Hash.
# File ../../device_api/trunk/ruby/src/lib/tree.rb, line 85 def initialize json, config @config = config begin @tree = JSON::Parser.new(json, :symbolize_names => true, :max_nesting => false).parse rescue raise Mobi::Mtld::Da::Exception::DataFileException, 'Invalid Json data.' end if @tree.nil? || !@tree.kind_of?(Hash) raise Mobi::Mtld::Da::Exception::DataFileException, "Unable to load Json data." end if !@tree.has_key?(KEY_META) raise Mobi::Mtld::Da::Exception::DataFileException, "Bad data loaded into the tree." end if @tree[KEY_META][KEY_META_VERSION].to_f < MIN_JSON_VERSION raise Mobi::Mtld::Da::Exception::DataFileException, "DeviceAtlas json file must be v" + " #{MIN_JSON_VERSION} or greater. Please download a more recent version." end # Prepare the user-agent rules branch before we start recognition. # To maintain backwards compatibility - only do this if we have the ua rules # branch if @tree[Mobi::Mtld::Da::Device::UaProps::KEY_UA_RULES] && @config.include_ua_props @ua_props = Mobi::Mtld::Da::Device::UaProps.new(self) # stick in the tree so we can use it later # remove the UAR branch to save some memory elsif @tree[Mobi::Mtld::Da::Device::UaProps::KEY_UA_RULES] @tree.delete(Mobi::Mtld::Da::Device::UaProps::KEY_UA_RULES) end # Prepare client side properties. if @tree[Mobi::Mtld::Da::Device::ClientProps::KEY_CP_RULES] @client_props = Mobi::Mtld::Da::Device::ClientProps.new(self) end # cache values from the tree which are used by the API property_ids = @tree[KEY_PROPERTY_NAMES] max_property_ids = property_ids.size - 1 for i in 0..max_property_ids if KEY_DEVICE_ID == property_ids[i] @device_id_prop_name_id = i.to_s.to_sym break end end # set ua headers @stock_ua_headers = [ "x-device-user-agent", "x-original-user-agent", "x-operamini-phone-ua", "x-skyfire-phone", "x-bolt-phone-ua", "device-stock-ua", "x-ucbrowser-ua", "x-ucbrowser-device-ua", "x-ucbrowser-device", "x-puffin-ua" ] # update stock user-agent headers from tree headers = @tree[KEY_HEADERS] if !headers.nil? ua_stock_headers = headers[KEY_UA_STOCK_HEADERS] if !ua_stock_headers.nil? @stock_ua_headers = ua_stock_headers end end # set data revision @data_revision = @tree[KEY_META][KEY_META_REVISION] end
Get data file creation timestamp
# File ../../device_api/trunk/ruby/src/lib/tree.rb, line 173 def data_creation_timestamp return @tree[KEY_META][KEY_META_TIMESTAMP] end
Get data file version
# File ../../device_api/trunk/ruby/src/lib/tree.rb, line 168 def data_version return @tree[KEY_META][KEY_META_VERSION] end
# File ../../device_api/trunk/ruby/src/lib/tree.rb, line 265 def property_name_by_id property_id return @tree[KEY_PROPERTY_NAMES][property_id] end
Get the list of all available property names from the tree (not contains client side props)
# File ../../device_api/trunk/ruby/src/lib/tree.rb, line 163 def property_names return @tree[KEY_PROPERTY_NAMES] end
# File ../../device_api/trunk/ruby/src/lib/tree.rb, line 269 def property_value_by_id value_id return @tree[KEY_VALUES][value_id] end
Get properties from tree walk/ua/client-side and put them in the tree.properties
user_agent
user-agent string (from the original User-Agent header) to be
used for detecting ua-props
stock_user_agents
list of candidate user-agent strings to be used for
tree walk
client_side_properties
optional client side properties
# File ../../device_api/trunk/ruby/src/lib/tree.rb, line 184 def put_properties user_agent, stock_user_agents, client_side_properties = nil # reset properties @properties = Mobi::Mtld::Da::Properties.new put_tree_walk_properties user_agent, stock_user_agents if !client_side_properties.nil? && !client_side_properties.empty? if @client_props.nil? # stop if the JSON file does not contain the required CPR section raise Mobi::Mtld::Da::Exception::ClientPropertiesException, "JSON data does not support client " + "properties." end @client_props.put_properties client_side_properties end end
Get properties from tree walk/ua and put them in the tree.properties
if !stock_user_agents.nil?
- iterate over stockUserAgents for each item: tree-walk and stop iteration if result has deviceId - use userAgent for detecting the ua-props
if stock_user_agents.nil?
- use userAgent for tree walk - use userAgent for detecting the ua-props
user_agent
user-agent string (from the original User-Agent header)
stock_user_agents
list of candidate user-agent strings to be used for
tree walk
# File ../../device_api/trunk/ruby/src/lib/tree.rb, line 212 def put_tree_walk_properties user_agent, stock_user_agents = nil include_ua_props = @config.include_ua_props # props_to_vals = {property-id-from-tree-p: value-id-from-tree-v,} props_to_vals = {} regexes = @tree[KEY_REGEX][API_ID.to_s.to_sym] tree_main = @tree[KEY_MAIN] matched = "" user_agent.strip! if stock_user_agents.nil? seek_properties tree_main, user_agent, props_to_vals, matched, regexes else stock_user_agents.each do |stock_user_agent| seek_properties(tree_main, stock_user_agent, props_to_vals, matched, regexes) if !props_to_vals[@device_id_prop_name_id].nil? break end end end # put the detected properties which are as # {property-id-from-tree-p: value-id-from-tree-v,} # into the (Properties) properties object props_to_vals.each do |property_id, value_id| name = property_name_by_id property_id.to_s.to_i @properties[name[1..name.length].to_sym] = Mobi::Mtld::Da::Property.new(property_value_by_id(value_id), name[0,1]) end # matched and un-matched if @config.include_match_info # add in matched and unmatched UA parts @properties[:"_matched"] = Mobi::Mtld::Da::Property.new(matched, Mobi::Mtld::Da::DataType::STRING) @properties[:"_unmatched"] = Mobi::Mtld::Da::Property.new( user_agent[matched.length..user_agent.length], Mobi::Mtld::Da::DataType::STRING) end # get ua-props from the original user-agent header if include_ua_props && !@ua_props.nil? @ua_props.put_properties user_agent, props_to_vals end end