Elive::Entity::Preload - Elluminate Preload instance class


Elive documentation Contained in the Elive distribution.

Index


Code Index:

NAME

Top

Elive::Entity::Preload - Elluminate Preload instance class

DESCRIPTION

This is the entity class for meeting preloads.

    my $preloads = Elive::Entity::Preload->list(
                        filter =>  'mimeType=application/x-shockwave-flash',
                    );

    my $preload = Elive::Entity::Preload->retrieve([$preload_id]);

    my $type = $preload->type;

There are three possible types of preloads: media, plan and whiteboard.

METHODS

Top

upload

    #
    # upload from a file
    #
    my $preload1 = Elive::Entity::Preload->upload('mypreloads/intro.wbd');

    #
    # upload in-memory data
    #
    my $preload2 = Elive::Entity::Preload->upload(
             {
		    type => 'whiteboard',
		    name => 'introduction.wbd',
		    ownerId => 357147617360,
                    data => $binary_data,
	     },
         );

Upload data from a client and create a preload. If a mimeType is not supplied, it will be guessed from the fileName extension, using MIME::Types.

download

    my $preload = Elive::Entity::Preload->retrieve([$preload_id]);
    my $binary_data = $preload->download;

Download data for a preload.

import_from_server

    my $preload1 = Elive::Entity::Preload->import_from_server(
             {
		    type => 'whiteboard',
		    name => 'introduction.wbd',
		    ownerId => 357147617360,
                    fileName => $path_on_server
	     },
         );

Create a preload from a file that is already present on the server. If a mimeType is not supplied, it will be guessed from the fileName extension using MIME::Types.

list_meeting_preloads

my $preloads = Elive::Entity::Preload->list_meeting_preloads($meeting_id);

Implements the listMeetingPreloads method

update

The update method is not available for preloads.

BUGS AND LIMITATIONS

Top

-- Under Elluminate 9.6.0 and LDAP, you may need to arbitrarily add a 'DomN:' prefix to the owner ID, when creating or updating a meeting.
    $preload->ownerId('Dom1:freddy');

-- Elluminate 10.0 strips the file extension from the filename when whiteboard files are saved or uploaded (introduction.wbd => introduction). However, if the file lacks an extension to begin with, the request crashes with the confusing error message: "string index out of range: -1".

Elive documentation Contained in the Elive distribution.
package Elive::Entity::Preload;
use warnings; use strict;

use Mouse;
use Mouse::Util::TypeConstraints;

extends 'Elive::Entity';

use Elive::Util;

use SOAP::Lite;  # contains SOAP::Data package
use MIME::Types;
use File::Basename qw{};

use Carp;

__PACKAGE__->entity_name('Preload');
__PACKAGE__->collection_name('Preloads');

has 'preloadId' => (is => 'rw', isa => 'Int', required => 1);
__PACKAGE__->primary_key('preloadId');
__PACKAGE__->params(
    meetingId => 'Str',
    fileName => 'Str',
    length => 'Int',
    );
__PACKAGE__->_alias(key => 'preloadId');

enum enumPreloadTypes => qw(media whiteboard plan);
has 'type' => (is => 'rw', isa => 'enumPreloadTypes', required => 1,
	       documentation => 'preload type. media, whiteboard or plan',
    );

has 'name' => (is => 'rw', isa => 'Str', required => 1,
	       documentation => 'preload name, e.g. "intro.wbd"',
    );

has 'mimeType' => (is => 'rw', isa => 'Str', required => 1,
		   documentation => 'The mimetype of the preload (e.g., video/quicktime).');

has 'ownerId' => (is => 'rw', isa => 'Str', required => 1,
		 documentation => 'preload owner (userId)',
    );

has 'size' => (is => 'rw', isa => 'Int', required => 1,
	       documentation => 'The length of the preload in bytes',
    );

has 'data' => (is => 'rw', isa => 'Str',
	       documentation => 'The contents of the preload.');

has 'isProtected' => (is => 'rw', isa => 'Bool');
has 'isDataAvailable' => (is => 'rw', isa => 'Bool');

sub BUILDARGS {
    my $class = shift;
    my $spec = shift;

    my %args;

    if ($spec && ! ref($spec) ) {
	#
	# Assume a single string arguments represents the local path of a file
	# to be uploaded.
	#
	my $preload_path = $spec;

	my $preload_basename = File::Basename::basename( $preload_path );
	croak "unable to determine a basename for preload path: $preload_path"
	    unless length $preload_basename;

	open ( my $fh, '<', $preload_path)
	    or die "unable to open preload file $preload_path";

	$fh->binmode;
	my $content = do {local $/; <$fh>};

	close $fh;

	die "upload file is empty: $preload_path"
	    unless length $content;

	%args = (
	    name => $preload_basename,
	    data => $content,
	);
    }
    elsif (Elive::Util::_reftype($spec) eq 'HASH') {
	%args = %$spec;
    }
    else {
	croak 'usage: '.$class.'->new( filepath | {name => $filename, data => $binary_data, ...} )';
    }

    if ($args{data}) {
	$args{size} ||= length( $args{data} );
    }

    die "unable to determine file name"
	unless defined $args{name} && length $args{name};

    $args{mimeType} ||= $class->_guess_mimetype($args{name});
    $args{type} ||= ($args{name} =~ m{\.wbd$}ix     ? 'whiteboard'
		     : $args{name} =~ m{\.elpx?$}ix ? 'plan'
		     : 'media');

    return \%args;
}

sub upload {
    my ($class, $spec, %opt) = @_;

    my $connection = $opt{connection} || $class->connection
	or die "not connected";

    my $insert_data = $class->BUILDARGS( $spec );
    my $content = delete $insert_data->{data};
    $insert_data->{ownerId} ||= $connection->login->userId;
    #
    # 1. create initial record
    #
    my $self = $class->insert($insert_data, %opt);

    if ($self->size && $content) {
	#
	# 2. Now upload data to it
	#
	my $som = $connection->call('streamPreload',
				    preloadId => $self->preloadId,
				    length => $self->size,
				    stream => (SOAP::Data
					       ->type('hexBinary')
					       ->value($content)),
	    );

	$connection->_check_for_errors($som);
    }

    return $self;
}

sub download {
    my ($self, %opt) = @_;

    my $preload_id = $opt{preload_id} ||= $self->preloadId;

    die "unable to get a preload_id"
	unless $preload_id;

    my $connection = $self->connection
	or die "not connected";

    my $som = $connection->call('getPreloadStream',
				%{$self->_freeze({preloadId => $preload_id})}
	);

    my $results = $self->_get_results($som, $connection);

    return  Elive::Util::_hex_decode($results->[0])
	if $results->[0];

    return;
}

sub import_from_server {
    my ($class, $spec, %opt) = @_;

    my $insert_data = $class->BUILDARGS($spec);

    die "missing required parameter: fileName"
	unless $insert_data->{fileName};

    $opt{command} ||= 'importPreload';

    return $class->insert($insert_data, %opt);
}

sub list_meeting_preloads {
    my ($self, $meeting_id, %opt) = @_;

    die 'usage: $preload_obj->list_meeting_preloads($meeting)'
	unless $meeting_id;

    $opt{command} ||= 'listMeetingPreloads';

    return $self->_fetch({meetingId => $meeting_id}, %opt);
}

sub _freeze {
    my ($class, $db_data, %opt) = @_;

    $db_data = $class->SUPER::_freeze( $db_data, %opt);

    if (my $filename = $db_data->{fileName}) {
	$db_data->{name} ||= File::Basename::basename( $filename );
    }

    if ($db_data->{name}) {

	$_ = File::Basename::basename($_)
	    for $db_data->{name};

    }

    return $db_data;
}

sub _thaw {
    my ($class, $db_data, %opt) = @_;

    my $db_thawed = $class->SUPER::_thaw($db_data, %opt);

    for (grep {defined} $db_thawed->{type}) {
	#
	# Just to pass type constraints
	#
	$_ = lc($_);

	unless (m{^media|whiteboard|plan$}x) {
	    Carp::carp "ignoring unknown media type: $_";
	    delete $db_thawed->{type};
	}
    }

    return $db_thawed;
}

sub update {return shift->_not_available}

sub _guess_mimetype {
    my ($class, $filename) = @_;

    our $mime_types ||= MIME::Types->new;
    my $mime_type;
    my $guess;

    unless ($filename =~ m{\.elpx?}x) { # plan
	$mime_type = $mime_types->mimeTypeOf($filename);

	$guess = $mime_type->type
	    if $mime_type;
    }

    $guess ||= 'application/octet-stream';

    return $guess;
}

sub _readback_check {
    my ($class, $update_ref, $rows, @args) = @_;

    #
    # Elluminate 10.0 discards the file extension for whiteboard preloads;
    # bypass check on 'name'.
    #

    my %updates = %{ $update_ref };
    delete $updates{name};

    return $class->SUPER::_readback_check(\%updates, $rows, @args, case_insensitive => 1);
}

1;