Net::TiVo::Folder - Class that wraps the XML description that defines a TiVo


Net-TiVo documentation Contained in the Net-TiVo distribution.

Index


Code Index:

NAME

Top

Net::TiVo::Folder - Class that wraps the XML description that defines a TiVo folder.

SYNOPSIS

Top

    use Net::TiVo;

    my $tivo = Net::TiVo->new(
        host => '192.168.1.25', 
        mac  => 'MEDIA_ACCESS_KEY'
    );

    for my $folder ($tivo->folders()) {
        print $folder->as_string(), "\n";
    }

DESCRPTION

Top

Net::TiVo::Folder provides an object-oriented interface to an XML description of a TiVo show. It provides the necessary accessors to read the XML data.

METHODS

content_type()

Returns TiVo's mime type for a folder (x-tivo-container/tivo-videos).

format()

Returns TiVo's mime type for the format of the folder (x-tivo-container/tivo-dvr).

change_date()

Returns the last time the folder was changed. The value is in seconds since the epoch.

name()

Returns the name of the folder.

total_items()

Returns the number of shows contained in this folder.

global_sort()

Returns a boolean (Yes or No) indicating if the folder is globally sorted.

sort_order()

Returns the sort order of the folder.

size()

Returns the size in bytes of this folder. This value is calculated by summing the individual shows contained in this folder.

shows()

Returns an array of the shows contained in this folder.

as_string()

Returns a pretty print of this folder's information, including name, number of show, size, and a list of shows contained in the folder.

SEE ALSO

Top

Net::TiVo, Net::TiVo::Show

AUTHOR

Top

Christopher Boumenot, <boumenot@gmail.com>


Net-TiVo documentation Contained in the Net-TiVo distribution.

# $Id: Folder.pm 57 2007-01-12 19:26:09Z boumenot $
# Author: Christopher Boumenot <boumenot@gmail.com>
######################################################################
#
# Copyright 2006-2007 by Christopher Boumenot.  This program is free 
# software; you can redistribute it and/or modify it under the same
# terms as Perl itself.
#
######################################################################

package Net::TiVo::Folder;

use strict;
use warnings;

use Text::Wrap;
use Log::Log4perl qw(:easy get_logger);

# Should be read as a poor man's XPath
our %DEFAULT_ATTRIBUTES_XPATH = (
    content_type => [qw(Details ContentType)],
    format       => [qw(Details SourceFormat)],
    change_date  => [qw(Details LastChangeDate)],
    name         => [qw(Details Title)],
    total_items  => [qw(Details TotalItems)],
    # Is this the same thing as total_items()?
    item_count   => [qw(ItemCount)],
    # What value is this?
    item_start   => [qw(ItemStart)],
    global_sort  => [qw(GlobalSort)],
    sort_order   => [qw(SortOrder)],
    # Due to the way folders are created it is difficult
    # to get the url of the folder.  I could add it easily
    # enough, but it would be a hack, and I'm not sure 
    # that you really need the url of the folder.  I need
    # to fix the code.
    #url
);

__PACKAGE__->make_accessor($_) for keys %DEFAULT_ATTRIBUTES_XPATH;
__PACKAGE__->make_accessor($_) for qw(size);
__PACKAGE__->make_array_accessor($_) for qw(shows);

sub TIVO_MIME_TYPES { qw(video/x-tivo-mpeg video/x-tivo-raw-pes video/x-tivo-raw-tts) }

sub new {
    my ($class, %options) = @_;
    
    unless ($options{xmlref}) {
        die __PACKAGE__ . ": Mandatory param xmlref missing\n";
    }

    my $self = {
        %options,
    };

    bless $self, $class;

    for my $attr (keys %DEFAULT_ATTRIBUTES_XPATH) {
        my $value = __PACKAGE__->walk_hash_ref($options{xmlref}, $DEFAULT_ATTRIBUTES_XPATH{$attr});
        $self->$attr($value);
    }

    $self->change_date(hex($self->change_date()));

#    DEBUG(sub { Data::Dumper::Dumper($options{xmlref}) });

    my ($size, @shows);
    for my $show (@{$options{xmlref}->{Item}}) {
        if (grep {$show->{Links}->{Content}->{ContentType} eq $_} TIVO_MIME_TYPES) {
            push @shows, Net::TiVo::Show->new(xmlref => $show);
            INFO("added the show " . $shows[-1]->name());
            $size += $shows[-1]->size();
        } 
    }

    $self->size($size);
    $self->shows(\@shows);
    
    return $self;
}

sub _commify {
    my ($self, $num) = @_;
    $num = reverse $num;
    $num =~ s<(\d\d\d)(?=\d)(?!\d*\.)><$1,>g;
    $num = reverse $num;
    return $num;
}

sub as_string {
    my $self = shift;

    $Text::Wrap::columns = 72;

    my @a;
    push @a, $self->name();
    push @a, sprintf("%d %s", $self->total_items(), (($self->total_items() > 1) ? "episodes" : "episode"));
    push @a, sprintf("%s bytes", $self->_commify($self->size()));
    my $s = wrap("", "      ", join(", ", @a));
    return $s;
}

# cmb - taken from the excellent Net::Amazon!
sub make_accessor {
    my($package, $name) = @_;

    no strict qw(refs);

    my $code = <<EOT;
    *{"$package\\::$name"} = sub {
        my(\$self, \$value) = \@_;

        if(defined \$value) {
            \$self->{$name} = \$value;
        }
        if(exists \$self->{$name}) {
            return (\$self->{$name});
        } else {
            return "";
        }
    }
EOT
    if(! defined *{"$package\::$name"}) {
        eval $code or die "$@";
    }
}

# cmb - taken from the excellent Net::Amazon!
sub make_array_accessor {
    my($package, $name) = @_;

    no strict qw(refs);

    my $code = <<EOT;
    *{"$package\\::$name"} = sub {
        my(\$self, \$nameref) = \@_;
        if(defined \$nameref) {
            if(ref \$nameref eq "ARRAY") {
                \$self->{$name} = \$nameref;
            } else {
                \$self->{$name} = [\$nameref];
            }
        }
        # Return a list
        if(exists \$self->{$name} and
           ref \$self->{$name} eq "ARRAY") {
            return \@{\$self->{$name}};
        }

        return undef;
    }
EOT

    if(! defined *{"$package\::$name"}) {
        eval $code or die "$@";
    }
}

sub walk_hash_ref {
    my ($package, $href, $aref) = @_;

    return $href if scalar(@$aref) == 0;

    my @a;
    push @a, $_ for @$aref;

    my $tail = pop @a;
    my $ref = $href;

    for my $part (@a) {
        $ref = $ref->{$part};
    }
    
    return $ref->{$tail};
}

1;

__END__