package WWW::Google::Notebook; use strict; use warnings; use base qw(Class::Accessor::Fast); use Carp; use URI; use URI::Escape (); use LWP::UserAgent; use WWW::Google::Notebook::Note; use WWW::Google::Notebook::Notebook; our $VERSION = '0.01'; __PACKAGE__->mk_accessors(qw/username password/); my $BaseURI = 'http://www.google.com/notebook/'; sub new { my ($class, %param) = @_; bless { username => $param{username} || '', password => $param{password} || '', }, $class; } sub ua { my $self = shift; if (@_) { $self->{ua} = shift; } else { $self->{ua} and return $self->{ua}; $self->{ua} = LWP::UserAgent->new; $self->{ua}->agent(__PACKAGE__."/$VERSION"); } $self->{ua}; } sub login { my ($self, %param) = @_; my $uri = URI->new('https://www.google.com/accounts/ServiceLoginAuth'); $uri->query_form( Email => $self->username, Passwd => $self->password, service => 'notebook', continue => $BaseURI, source => __PACKAGE__."/$VERSION", ); my $res = $self->ua->post($uri); croak($res->status_line) if $res->is_error; my $cookie = $res->header('Set-Cookie'); $self->ua->default_header(Cookie => $cookie); $res = $self->ua->post($BaseURI.'token?&pv=2'); croak($res->status_line) if $res->is_error; my ($token) = $res->content =~ m!/\*(.*)\*/!; $self->{_token} = $token; return 1; } sub notebooks { my $self = shift; my $uri = sprintf( $BaseURI.'read?pv=2&ident=fp&tok=%s&cmd=u&zx=%d', $self->{_token}, time, ); my $res = $self->ua->get($uri); croak($res->status_line) if $res->is_error; my $notebooks = $self->_parse($res->content); $notebooks; } sub add_notebook { my ($self, $title) = @_; my $uri = sprintf( $BaseURI.'write?pv=2&ident=fp&tok=%s&cmd=b&contents=%s', $self->{_token}, _uri_escape($title), ); my $res = $self->ua->post($uri); croak($res->status_line) if $res->is_error; my $notebook = $self->_parse($res->content); $notebook; } sub _delete_notebook { my ($self, $notebook) = @_; my $uri = sprintf( $BaseURI.'write?pv=2&ident=fp&tok=%s&cmd=trshn&nbid=%s', $self->{_token}, $notebook->id, ); my $res = $self->ua->post($uri); croak($res->status_line) if $res->is_error; undef %$notebook; bless $notebook, 'WWW::Google::Notebook::Object::Has::Been::Deleted'; 1; } sub _update_notebook { my ($self, $notebook) = @_; my $uri = sprintf( $BaseURI.'write?pv=2&ident=fp&tok=%s&cmd=b&nbid=%s&contents=%s', $self->{_token}, $notebook->id, _uri_escape($notebook->title), ); my $res = $self->ua->post($uri); croak($res->status_line) if $res->is_error; $notebook = $self->_parse($res->content); 1; } sub _notes { my ($self, $notebook) = @_; my $uri = sprintf( $BaseURI.'read?pv=2&ident=fp&tok=%s&cmd=b&nbid=%s&zx=%d', $self->{_token}, $notebook->id, time, ); my $res = $self->ua->get($uri); croak($res->status_line) if $res->is_error; print $res->content; $notebook = $self->_parse($res->content); my @notes; for my $note (@{$notebook->{_notes}}) { $note->notebook($notebook); push @notes, $note; } undef $notebook->{_notes}; \@notes; } sub _add_note { my ($self, $notebook, $content) = @_; $content =~ s/\r?\n/
/g; my $uri = sprintf( $BaseURI.'write?pv=2&ident=fp&tok=%s&cmd=n&nbid=%s&contents=%s&qurl=null&nmeth=fp', $self->{_token}, $notebook->id, _uri_escape($content), ); my $res = $self->ua->post($uri); croak($res->status_line) if $res->is_error; my $note = $self->_parse($res->content); $note->notebook($notebook); $note; } sub _delete_note { my ($self, $note) = @_; my $uri = sprintf( $BaseURI.'write?pv=2&ident=fp&tok=%s&cmd=trsh&nid=%s&nbid=%s', $self->{_token}, $note->id, $note->notebook->id, ); my $res = $self->ua->post($uri); croak($res->status_line) if $res->is_error; undef %$note; bless $note, 'WWW::Google::Notebook::Object::Has::Been::Deleted'; 1; } sub _update_note { my ($self, $note) = @_; my $uri = sprintf( $BaseURI.'write?pv=2&ident=fp&tok=%s&cmd=n&nbid=%s&nid=%s&contents=%s&qurl=null', $self->{_token}, $note->notebook->id, $note->id, _uri_escape($note->content), ); my $res = $self->ua->post($uri); croak($res->status_line) if $res->is_error; $note = $self->_parse($res->content); 1; } sub _parse { my ($self, $json) = @_; no warnings 'once'; local *F = sub {}; local *U = sub { $_[0] }; local *B = sub { WWW::Google::Notebook::Notebook->new({ id => $_[0], title => $_[1], api => $self, _notes => $_[11]->[0] || [], }); }; local *N = sub { WWW::Google::Notebook::Note->new({ id => $_[0], content => $_[1], created_on => $_[5], }); }; local *S = sub { $_[3] }; eval $json; } sub _uri_escape { my $val = shift; $val =~ s/\r?\n/
/g; URI::Escape::uri_escape($val); } 1; __END__ =head1 NAME WWW::Google::Notebook - Perl interface for Google Notebook =head1 SYNOPSIS use WWW::Google::Notebook; my $google = WWW::Google::Notebook->new( username => $username, password => $password, ); $google->login; my $notebooks = $google->notebooks; # WWW::Google::Notebook::Notebook object as arrayref for my $notebook (@$notebooks) { print $notebook->title, "\n"; my $notes = $notebook->notes; # WWW::Google::Notebook::Note object as arrayref for my $note (@$notes) { print $note->content, "\n"; } } my $notebook = $google->add_notebook('title'); # WWW::Google::Notebook::Notebook object print $notebook->title; $notebook->rename('title2'); my $note = $notebook->add_note('note'); # WWW::Google::Notebook::Note object print $note->content; $note->edit('note2'); $note->delete; $notebook->delete; =head1 DESCRIPTION This module priovides you an Object Oriented interface for Google Notebook, using unofficial API. =head1 METHODS =head2 new(username => $username, password => $password) Returns an instance of this module. =head2 login Login to Google. =head2 notebooks Returns your notebooks as L objects. =head2 add_notebook($title) Adds notebook. Returns a created notebook as L object. =head1 ACCESSOR =over 4 =item username =item password =item ua =back =head1 AUTHOR Jiro Nishiguchi Ejiro@cpan.orgE This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =head1 SEE ALSO =over 4 =item * L =back =cut