BZ::Client - A client for the Bugzilla web services API.


BZ-Client documentation Contained in the BZ-Client distribution.

Index


Code Index:

NAME

Top

  BZ::Client - A client for the Bugzilla web services API.

SYNOPSIS

Top

  my $client = BZ::Client->new("url" => $url,
                               "user" => $user,
                               "password" => $password);
  $client->login();

CLASS METHODS

Top

This section lists the class methods of BZ::Client.

new

Top

  my $client = BZ::Client->new("url" => $url,
                               "user" => $user,
                               "password" => $password);

The new method constructs a new instance of BZ::Client. Whenever you want to connect to the Bugzilla server, you must first create a Bugzilla client. The methods input is a hash of parameters.

url

The Bugzilla servers URL, for example https://bugzilla.mozilla.org/.

user

The user name to use when logging in to the Bugzilla server. Typically, this will be your email address.

password

The password to use when logging in to the Bugzilla server.

INSTANCE METHODS

Top

This section lists the methods, which an instance of BZ::Client can perform.

url

  my $url = $client->url();
  $client->url($url);

Returns or sets the Bugzilla servers URL.

user

  my $user = $client->user();
  $client->user($user);

Returns or sets the user name to use when logging in to the Bugzilla server. Typically, this will be your email address.

password

  my $password = $client->password();
  $client->password($password);

Returns or sets the password to use when logging in to the Bugzilla server.

login

Used to login to the Bugzilla server. There is no need to call this method explicitly: It is done automatically, whenever required.

api_call

  my $response = $client->api_call($methodName, $params);

Used by subclasses of BZ::Client::API to invoke methods of the Bugzilla API. Takes a method name and a hash ref of parameters as input. Returns a hash ref of named result objects.

SEE ALSO

Top

  L<BZ::Client::Exception>


BZ-Client documentation Contained in the BZ-Client distribution.

#
# BZ::Client.pm - Web services client for the Bugzilla server
#

package BZ::Client;

use BZ::Client::XMLRPC();
use HTTP::Cookies();

our $VERSION = '1.03';


sub new($%) {
    my $class = shift;
    my $self = { @_ };
    bless($self, ref($class) || $class);
    return $self;
}

sub url($;$) {
    my $self = shift;
    if (@_) {
        $self->{'url'} = shift;
    } else {
        return $self->{'url'};
    }
}

sub user($;$) {
    my $self = shift;
    if (@_) {
        $self->{'user'} = shift;
    } else {
        return $self->{'user'};
    }
}

sub password($;$) {
    my $self = shift;
    if (@_) {
        $self->{'password'} = shift;
    } else {
        return $self->{'password'};
    }
}

sub error($$;$$) {
    my($self, $message, $http_code, $xmlrpc_code) = @_;
    require BZ::Client::Exception;
    BZ::Client::Exception->throw(message => $message,
                                 http_code => $http_code,
                                 xmlrpc_code => $xmlrpc_code);
}

sub log($$$) {
    my($self, $level, $msg) = @_;
    my $logger = $self->logger();
    if ($logger) {
        &$logger($level, $msg);
    }
}

sub logger($;$) {
    my($self) = shift;
    if (@_) {
        $self->{'logger'} = shift;
    } else {
        return $self->{'logger'};
    }
}

sub logDirectory($;$) {
    my($self) = shift;
    if (@_) {
        $self->{'logDirectory'} = shift;
    } else {
        return $self->{'logDirectory'};
    }
}

sub xmlrpc($;$) {
    my $self = shift;
    if (@_) {
        $self->{'xmlrpc'} = shift;
    } else {
        my $xmlrpc = $self->{'xmlrpc'};
        if (!$xmlrpc) {
            my $url = $self->url() || $self->error("The Bugzilla servers URL is not set.");
            $xmlrpc = BZ::Client::XMLRPC->new("url" => $url);
            $xmlrpc->logDirectory($self->logDirectory());
            $xmlrpc->logger($self->logger());
            $self->xmlrpc($xmlrpc);
        }
        return $xmlrpc;
    }
}

sub login($) {
    my $self = shift;
    my $user = $self->user() || $self->error("The Bugzilla servers user name is not set.");
    my $password = $self->password() || $self->error("The Bugzilla servers password is not set.");

    my $params = { "login" => $user,
                   "password" => $password,
                   "remember" => BZ::Client::XMLRPC::boolean->new(0) };
    my $cookies = HTTP::Cookies->new();
    my $response = $self->_api_call("User.login", $params, $cookies);
    if (!defined($response->{'id'})  ||  $response->{'id'} !~ /^\d+$/s) {
        $self->error("Server did not return a valid user ID.");
    }
    $self->{"cookies"} = $cookies;
    return;
}

sub logout($) {
    my $self = shift;
    my $cookies = $self->{"cookies"};
    if ($cookies) {
        $self->{"cookies"} = undef;
        my $xmlrpc = $self->xmlrpc();
        $xmlrpc->request("methodName" => "User.logout", params => [] );
    }
}

sub is_logged_in($) {
    my $self = shift;
    return $self->{"cookies"} ? 1 : 0;
}

sub api_call($$$) {
    my($self, $methodName, $params) = @_;
    if (!$self->is_logged_in()) {
        $self->login();
    }
    return $self->_api_call($methodName, $params);
}

sub _api_call($$$;$) {
    my($self, $methodName, $params, $cookies) = @_;
    $self->log("debug", "BZ::Client::_api_call, sending request for method $methodName to " . $self->url());
    my $xmlrpc = $self->xmlrpc();
    if ($cookies) {
        $xmlrpc->user_agent()->cookie_jar($cookies);
    }
    my $response = $xmlrpc->request("methodName" => $methodName, params => [ $params ] );
    if (!$response) {
        $self->error("Empty response from server.");
    }
    if (ref($response) ne "HASH") {
        $self->error("Invalid response from server: $response");
    }
    $self->log("debug", "BZ::Client::_api_call, got response for method $methodName");
    return $response;
}

1;