Copyright © 2013 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
Public static constant
# File ../Src/clientprops.rb, line 34 def initialize (tree) # Private constants @OPERATOR_EQUALS = "=" @OPERATOR_NOT_EQUALS = "!=" @OPERATOR_LESS_THAN = "<" @OPERATOR_LESS_THAN_EQUALS = "<=" @OPERATOR_GREATER_THAN = ">" @OPERATOR_GREATER_THAN_EQUALS = ">=" @USER_AGENT = "ua" # Table to replace HTML escape characters from property values in the cookie # content. @HTML_ESCAPE_CHARACTERS = { '&' => '&', '"' => '"', '<' => '<', '>' => '>' } super(tree, CP_RULES) end
Merge the tree walk properties with the client side properties and run any additional rules based on the client side and tree walk properties. The rules can define replacement or additional values for properties and can also provide a new User-Agent to be used for a second tree walk. This is typically a fake User-Agent mapped to a device that cannot normally be detected such as the various iPhone models.
detectedProperties
The results of the tree walk and UAR, map of property name to value.
clientProperties
The parsed client properties.
typedValues
Whether to return typed values or string values.
return
Associative array of properties or NULL if there are no properties.
# File ../Src/clientprops.rb, line 113 def getProperties(detectedProperties, clientProperties, typedValues) if clientProperties.nil? return detectedProperties end # Merge the tree walk properties with the client side properties and run any # additional rules based on the client side and tree walk properties. The # rules can define replacement or additional values for properties and can # also provide a new User-Agent to be used for a second tree walk. This is # typically a fake User-Agent mapped to a device that cannot normally be # detected such as the various iPhone models. PropsHandler::mergeProperties(detectedProperties, clientProperties) # using the merged properties to look up additional rules # STEP 1: try and find the rules to run on the UA ruleGroups = @branch[@RULE_GROUPS] rulesToRun = getRulesToRun(detectedProperties, ruleGroups, typedValues) # STEP 2: do second tree walk if necessary and replace/create any new # values based on the rules if !rulesToRun.nil? userAgent = rulesToRun.userAgent if !userAgent.nil? # use the UA for a second tree walk - note the last param is # false as we know the UA won't have any dynamic properties # also sought = nil api = DeviceAtlas.new secondTreeWalkProps = api.getProperties(@tree, userAgent, nil, typedValues, nil, false) # merge origProperties in to get any parent properties such as the dynamic properties # 2nd tree walk > first tree walk PropsHandler::mergeProperties(detectedProperties, secondTreeWalkProps) # the client properties still take priority so merge them in again # client props > tree walks PropsHandler::mergeProperties(detectedProperties, clientProperties) end # overlay the new properties ruleSet = rulesToRun.ruleSet ruleSet.each do |propIdValId| propId = propIdValId[@PROPERTY] propValId = propIdValId[@PROPERTY_VALUE] # get prop and val to set propName = PropsHandler::propertyFromId(@tree, propId) value = PropsHandler::getValue(@tree, propId, propValId, typedValues) # replace/create properties detectedProperties[propName] = value end end detectedProperties end
Parse the client side properties and if typed values is set convert the values to the appropriate type.
propStr
Cookie content with the form:
bjs.webGl:1|bjs.geoLocation:1|sdeviceAspectRatio:16/10|iusableDisplayHeight:1050 The first character of the property name is the type of the value.
typedValues
Whether to return typed values or string values.
# File ../Src/clientprops.rb, line 202 def parseClientSideProperties(propStr, typedValues) props = nil if propStr.nil? return props end begin propStr = propStr.strip propStr = propStr.gsub('"', '') props = {} doKey = true name = '' value = '' type = 0 # iterate over the property string looking for properties and values numChars = propStr.length - 1 for i in 0..numChars # Besides we can handle strings as arrays to access to specific positions, # we must consider that method doesn't work in the same way in Ruby 1.8 # and 1.9: # - 1.8: Returns the ASCII code of the character. # - 1.9: Returns the character. # # Therefore, if we want to be sure we always get a character, we have to # use the chr() function. c = propStr[i].chr case c when '|' # use our collected items appendPropVal(props, name, value, type, typedValues) # reset for next key/value doKey = true name = '' value = '' type = 0 next # skip to the next character when ':' doKey = false next # skip to the next character when '"' if i==0 || i==numChars next # skip any wrapping quotes end end if doKey if type==0 && (c == 'b' || c=='i' || c=='s' || c=='d') type = c else name += c.to_s end else value += c.to_s end end # add the last prop value appendPropVal(props, name, value, type, typedValues) rescue Exception => ex raise(ClientPropertiesException, "Could not decode client properties: " + ex.message) end props end
Check if a given property exists with a certain type. This follows the same logic as the Api.propertyTypeCheck() in that it really checks if a property exists and if it has the correct type.
cookie
The cookie string
property
The property to check
type
The type of the property
# File ../Src/clientprops.rb, line 186 def propertyTypeCheck(cookie, property, type) res = true if !cookie.nil? && !cookie[type+property] res = false end res end
Find all the properties that are used for matching. This is needed in case the Api.getProperty() function is called as we need these properties for the rules to work correctly
group
The rule group that can contain a property matcher.
propIds
The set of found property IDs.
return
An updated set of property IDs.
# File ../Src/clientprops.rb, line 65 def initGetMatcherPropertyIds(group, propIds) if group[@PROPERTY_MATCHER] propertyMatchers = group[@PROPERTY_MATCHER] propertyMatchers.each do |propertyMatcher| propId = propertyMatcher[@PROPERTY] if !propIds.include?(propId) propIds.push(propId) end end end propIds end
Prepare the rule set by extracting it from the current group and wrapping it in an ArrayList. This is done to remain compatible with initGetRulePropertyIds()
group
The current parent group.
return
A list of all rule sets.
# File ../Src/clientprops.rb, line 89 def initRuleSets(group) # wrap the single rule set in an array list. item = {} item[@RULE_ARR] = group[@RULE_ARR] ruleSets = [] ruleSets.push(item) ruleSets end