class UpnpContentExplorer::Explorer

Constants

DEFAULT_OPTIONS

Attributes

root[RW]

Public Class Methods

new(service, options = {}) click to toggle source
# File lib/upnp_content_explorer/explorer.rb, line 19
def initialize(service, options = {})
  @options = DEFAULT_OPTIONS.merge(options)
  @service = service
  @root = load_root_node(@options[:root_id])
end

Public Instance Methods

get(path) click to toggle source
# File lib/upnp_content_explorer/explorer.rb, line 25
def get(path)
  find_terminal_node(prepare_path(path))
end
root_path() click to toggle source
# File lib/upnp_content_explorer/explorer.rb, line 29
def root_path
  path = []
  current = @root

  while !current.nil? && current.id != Node::ROOT_ID
    path << current.title
    current = load_root_node(current.parent_id)
  end

  '/' << path.reverse.join('/')
end
scrape(path) click to toggle source
# File lib/upnp_content_explorer/explorer.rb, line 41
def scrape(path)
  node = find_terminal_node(prepare_path(path))

  child_items = node.children.map do |child|
    scrape("#{path}/#{child.title}")
  end

  all_items = []
  all_items += node.items
  all_items += child_items.flatten
end

Private Instance Methods

find_terminal_node(path, node = @root, traversed_path = '') click to toggle source
# File lib/upnp_content_explorer/explorer.rb, line 59
def find_terminal_node(path, node = @root, traversed_path = '')
  node.load!(get_node(node.id)) unless node.loaded?

  return node if path.empty?

  next_node = path.shift
  next_traversed_path = "#{traversed_path}/#{next_node}"
  child = node.child(next_node)

  raise PathNotFoundError, "Path doesn't exist: #{next_traversed_path}" if child.nil?

  find_terminal_node(path, child, next_traversed_path)
end
get_node(node_id) click to toggle source
# File lib/upnp_content_explorer/explorer.rb, line 91
def get_node(node_id)
  response = @service.Browse(
      ObjectID: node_id,
      BrowseFlag: 'BrowseDirectChildren',
      Filter: '*',
      StartingIndex: '0',
      RequestedCount: '0'
  )

  node_data = response[:Result]
    .gsub('xmlns=', 'xmlns:didl=')
  content = Nokogiri::XML(node_data)
  content.remove_namespaces!

  children = content.xpath('/DIDL-Lite/container').map do |child|
    node_data = parse_nori_node(child)
    Node.new(node_data)
  end

  items = content.xpath('/DIDL-Lite/item').map do |item|
    Item.new(item)
  end

  children = Hash[ children.map { |x| [x.title, x] } ]
  items = Hash[ items.map { |x| [x.title, x] } ]

  { children: children, items: items }
end
load_root_node(id) click to toggle source
# File lib/upnp_content_explorer/explorer.rb, line 73
def load_root_node(id)
  node = Node.new(id: id)
  response = @service.Browse(
      ObjectID: id,
      BrowseFlag: 'BrowseMetadata',
      Filter: '*',
      StartingIndex: '0',
      RequestedCount: '0'
  )

  node_xml = Nokogiri::XML(response[:Result])
  node_xml.remove_namespaces!
  node_data = parse_nori_node(node_xml.xpath('//DIDL-Lite/container'))

  node.load!(node_data, false)
  node
end
parse_nori_node(node) click to toggle source
# File lib/upnp_content_explorer/explorer.rb, line 120
def parse_nori_node(node)
  raw_map = Nori.new(:strip_namespaces => true).parse(node.to_xml)
  raw_map = raw_map[raw_map.keys.first]

  Hash[
      raw_map.map do |k,v|
        [k.gsub('@', '').to_sym, v]
      end
  ]
end
prepare_path(path) click to toggle source
# File lib/upnp_content_explorer/explorer.rb, line 54
def prepare_path(path)
  path = Pathname.new(path)
  path.each_filename.to_a
end