class Mobi::Mtld::Da::Device::ClientProps

Copyright
Author

Constants

KEY_CP_RULES

Constants to make keys more readable

KEY_USER_AGENT

Public Class Methods

new(tree) click to toggle source
Calls superclass method
# File ../../device_api/trunk/ruby/src/lib/client_props.rb, line 23
def initialize tree
        super(tree, KEY_CP_RULES)
end

Public Instance Methods

parse_client_side_properties(client_side_properties) click to toggle source

Parse the client side properties and if typed values is set convert the values to the appropriate type.

prop_str

Cookie content with the form:

bjs.webGl:1|sdeviceAspectRatio:16/10|iusableDisplayHeight:1050

The first character of the property name is the type of the value.

# File ../../device_api/trunk/ruby/src/lib/client_props.rb, line 97
    def parse_client_side_properties client_side_properties
    # Table to replace HTML escape characters from property values in the cookie
    # content.
html_escape_characters = {'&' => '&amp;', '"' => '&quot;', '<' => '&lt;',
  '>' => '&gt;'}

props = {}
client_side_properties.strip!

            begin

  name = ''
  value = ''
  is_key = true
  is_type = true
  key_ok = true
  type = 0

  num_chars = client_side_properties.length - 1

                    # iterate over the property string looking for properties and values
                    for i in 0..num_chars

                            # Besides we can handle strings as arrays to access to specific position
    # s, 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 = client_side_properties[i].chr

                            case c
                            when '|'

      # if key is valid add property
      if key_ok
        type = name[0,1]
        props[name] = value # No need of typifying it
        @tree_provider.properties[name[1..name.length].to_sym] =
          Mobi::Mtld::Da::Property.new(value, type)
      end

      # reset for next key/value
      name = ''
      value = ''
      is_key = true
      key_ok = true
      is_type = true

                                    next # skip to the next character
                            when ':'
                                    is_key = false
                                    next # skip to the next character
                            when '"'
      if i < num_chars
        next_c = client_side_properties[i+1]
      else
        next_c = 0
      end
                                    if i == 0 || i == num_chars || is_key || value.length == 0 ||
          next_c == '|' || next_c == '"'
                                            next # skip any wrapping quotes
                                    end
                            end

    if is_key
      # check if property type and name are correct
      if is_type
        if c != 'b' && c != 'i' && c != 's' && c != 'd'
          key_ok = false
        end
        is_type = false
      else
        c_ord = c[0].ord # Get the first and only char as "c" is a String
        if (c_ord < 48 && c_ord != 46) || c_ord > 122 ||
            (c_ord > 57 && c_ord < 65) || (c_ord > 90 && c_ord < 97)
          key_ok = false
        end
      end
      name << c.to_s
    else
      # Replace HTML escape characters: &"<>
      # Same as CGI::escapeHTML().
      if html_escape_characters.has_key?c
        value << html_escape_characters[c]
      else
        value << c.to_s
      end
    end

  end # for

  # add the last prop value
  if key_ok
    type = name[0,1]
    props[name] = value # No need of typifying it
    @tree_provider.properties[name[1..name.length].to_sym] =
      Mobi::Mtld::Da::Property.new(value, type)
  end

            rescue Exception => ex
                    raise Mobi::Mtld::Da::Exception::ClientPropertiesException,
    "Could not decode client properties: #{ex.message}"
            end

            return props
    end
put_properties(client_side_properties) click to toggle source

Put Client Side properties into the property set.

client_side_properties

Cookie content with the following format:

bjs.webGl:1|sdeviceAspectRatio:16/10|iusableDisplayHeight:1050

The first character of the property name is the type of the value.

# File ../../device_api/trunk/ruby/src/lib/client_props.rb, line 33
def put_properties client_side_properties

  # "merge with detected properties" and "get" the props from the client side
  # cookie
  client_side_properties = parse_client_side_properties client_side_properties

  # use the merged properties to look up additional rules

  # STEP 1: try and find the rules to run on the UA
              rule_groups = @branch[KEY_RULE_GROUPS]
  rules_to_run = rules_to_run rule_groups

  # STEP 2: do second tree walk if necessary and replace/create any new
  # values based on the rules
  if rules_to_run.nil?
    return
  end

  user_agent = rules_to_run.user_agent

  if !user_agent.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
    @tree_provider.put_tree_walk_properties user_agent

    # merge origProperties in to get any parent properties such as the dynamic
    # properties
    # 2nd tree walk > first tree walk

    # the client properties still take priority so merge them in again
    # client props > tree walks

    client_side_properties.each do |name, value|
      @tree_provider.properties[name[1..name.length].to_sym] =
        Mobi::Mtld::Da::Property.new(value, name[0,1])
    end

  end

  # overlay the new properties
  rule_set = rules_to_run.rule_set
  max_rule_set = rule_set.size - 1

  for i in 0..max_rule_set
    prop_id_val_id = rule_set[i]
    name = @tree_provider.property_name_by_id(
      prop_id_val_id[KEY_PROPERTY_MATCHER])
    @tree_provider.properties[name[1..name.length].to_sym] =
      Mobi::Mtld::Da::Property.new(
      @tree_provider.property_value_by_id(prop_id_val_id[KEY_PROPERTY_VALUE]),
      name[0,1])
  end

end

Protected Instance Methods

init_get_matcher_propery_ids(group, prop_ids) click to toggle source

Find all the properties that are used for matching.

group

The rule group that can contain a property matcher.

prop_ids

The set of found property IDs.

return

An updated set of property IDs.

# File ../../device_api/trunk/ruby/src/lib/client_props.rb, line 214
def init_get_matcher_propery_ids group, prop_ids
              if group[KEY_PROPERTY_MATCHER]
                      property_matchers = group[KEY_PROPERTY_MATCHER]
    max_property_matchers = property_matchers.size - 1
    for i in 0..max_property_matchers
      property_matcher = property_matchers[i]
                              prop_id = property_matcher[KEY_PROPERTY_MATCHER]
                              if !prop_ids.include?(prop_id)
                                      prop_ids.push(prop_id)
                              end
                      end
              end
              return prop_ids
      end
init_rule_sets(group) click to toggle source

Prepare the rule set by extracting it from the current group and wrapping it in an Array.

group

The current parent group.

return

A list of all rule sets.

# File ../../device_api/trunk/ruby/src/lib/client_props.rb, line 234
def init_rule_sets group
        # wrap the single rule set in an array list.
        return [{ KEY_RULE_ARR => group[KEY_RULE_ARR] }]
end