=================================================================== RCS file: /cvs/todotxt/Text-Todo-REST-API/lib/Text/Todo/REST/API.pm,v retrieving revision 1.2 retrieving revision 1.7 diff -u -r1.2 -r1.7 --- todotxt/Text-Todo-REST-API/lib/Text/Todo/REST/API.pm 2010/01/17 23:15:00 1.2 +++ todotxt/Text-Todo-REST-API/lib/Text/Todo/REST/API.pm 2010/01/18 13:47:53 1.7 @@ -1,6 +1,6 @@ package Text::Todo::REST::API; -# $AFresh1$ +# $AFresh1: API.pm,v 1.6 2010/01/18 03:51:40 andrew Exp $ use warnings; use strict; @@ -9,9 +9,12 @@ use Data::Dumper; use Text::Todo; -use Class::Std; +use Class::Std::Utils; +use Module::Pluggable + require => 1, + search_path => __PACKAGE__ . '::Representations', + sub_name => 'representations'; use Digest::MD5 qw/ md5_hex /; -use File::Spec; use version; our $VERSION = qv('0.0.1'); @@ -24,15 +27,23 @@ ); { - my (%todo_of, %basedir_of, %subdir_of, - %suffix_of, %file_regex_of, %user_of, - %list_of, %action_of, %args_of, - %action_handlers, %format_handlers, - ) : ATTRS; + my @attr_refs = \( + my %todo_of, - sub BUILD { - my ( $self, $ident, $options ) = @_; + my %suffix_of, + my %file_regex_of, + my %user_of, + my %list_of, + my %action_of, + my %args_of, + + my %action_handlers, + ); + + sub new { + my ( $class, $options ) = @_; + my $format = $options->{default_format}; if ( $options->{format} ) { $format = $options->{format}; @@ -43,17 +54,23 @@ $format = $1; } + my $self = bless anon_scalar(), $class; + my $ident = ident($self); + if ( ref $self eq __PACKAGE__ && $format ) { - if ( $format_handlers{$format} ) { - bless $self, $format_handlers{$format}; + my $found_handler = 0; + REP: foreach my $rep ( $self->representations ) { + if ( $rep->_handles($format) ) { + $self = $rep->new($options); + $found_handler = 1; + last REP; + } } - else { + if ( !$found_handler ) { croak("Unable to find handler for [$format]\n"); } } - $basedir_of{$ident} = $options->{basedir}; - $subdir_of{$ident} = $options->{subdir}; $suffix_of{$ident} = $options->{suffix} || '.txt'; $file_regex_of{$ident} = $options->{file_regex} || qr{ @@ -64,62 +81,33 @@ $ }ixms; - if ( !$basedir_of{$ident} ) { - return $self->fail('Required option [basedir]'); - } - $options->{path_info} ||= q{}; $options->{path_info} =~ s{^/}{}xms; - ( $user_of{$ident}, $list_of{$ident}, - $action_of{$ident}, @{ $args_of{$ident} }, + ( $list_of{$ident}, $action_of{$ident}, @{ $args_of{$ident} }, ) = split '/', $options->{path_info}; if ( $list_of{$ident} ) { $action_of{$ident} ||= 'list'; } - elsif ( $user_of{$ident} ) { + else { $action_of{$ident} = 'files'; } - my @todo_dir = $basedir_of{$ident}; - - my $todo_dir; - if ( $user_of{$ident} ) { - push @todo_dir, $user_of{$ident}; - if ( $subdir_of{$ident} ) { - push @todo_dir, $subdir_of{$ident}; + eval { $todo_of{$ident} = Text::Todo->new( + { todo_dir => $options->{todo_dir}, + todo_file => $options->{todo_file}, } - - $todo_dir = File::Spec->catdir(@todo_dir); + ) }; + if ($@) { + $self->fail('Unable to create Text::Todo object' . $@); } - my $todo_file; - if ( $list_of{$ident} ) { - $todo_file = $list_of{$ident} . $suffix_of{$ident}; - } - - $todo_of{$ident} = Text::Todo->new( - { todo_dir => $todo_dir, - todo_file => $todo_file, - } - ) or $self->fail('Unable to create Text::Todo object'); - $todo_of{$ident}->load('todo_file') - or $self->fail('Unable to create Text::Todo object'); + or $self->fail('Unable to load todo_file in Text::Todo object'); - return; + return $self; } - sub RegisterFormatHandler { - my ( $handler, @types ) = @_; - - foreach my $type (@types) { - $format_handlers{$type} = $handler; - } - - return 1; - } - sub RegisterActionHandler { my ( $handler, @types ) = @_; @@ -130,6 +118,8 @@ return 1; } + sub content_type {return} + sub Dump { my ($self) = @_; return $self->fail( 'Unable to Dump [' . $self->_action . ']' ); @@ -140,17 +130,23 @@ return $self->fail( 'Unable to Load [' . $self->_action . ']' ); } - sub GET { - my ( $self, $params ) = @_; + sub _handle_action { + my ( $self, $method, $params ) = @_; - if ( exists $action_handlers{GET}{ $self->_action } ) { - my $method = $action_handlers{GET}{ $self->_action }; - return $self->$method( $self->_args, $params ); + if ( exists $action_handlers{$method}{ $self->_action } ) { + my $a = $action_handlers{$method}{ $self->_action }; + return $self->$a( $self->_args, $params ); } - return $self->fail( 'Unable to handle GET [' . $self->_action . ']' ); + return $self->fail( + 'Unable to handle ' . $method . ' [' . $self->_action . ']' ); } + sub GET { + my ( $self, @args ) = @_; + return $self->_handle_action( 'GET', @args ); + } + sub get_entry { my ( $self, $key ) = @_; @@ -225,18 +221,27 @@ return $todo_of{$ident}->listtag($tag); } - sub POST { croak "Unsupported [POST]" } - sub PUT { croak "Unsupported [PUT]" } - sub DELETE { croak "Unsupported [DELETE]" } + sub POST { + my ( $self, @args ) = @_; + return $self->_handle_action( 'POST', @args ); + } + sub PUT { + my ( $self, @args ) = @_; + return $self->_handle_action( 'PUT', @args ); + } + + sub DELETE { + my ( $self, @args ) = @_; + return $self->_handle_action( 'DELETE', @args ); + } + sub fail { my ( $self, @message ) = @_; croak(@message); } sub _todo { my ($self) = @_; return $todo_of{ ident $self }; } - sub _basedir { my ($self) = @_; return $basedir_of{ ident $self}; } - sub _subdir { my ($self) = @_; return $subdir_of{ ident $self}; } sub _suffix { my ($self) = @_; return $suffix_of{ ident $self}; } sub _file_regex { my ($self) = @_; return $file_regex_of{ ident $self}; } sub _user { my ($self) = @_; return $user_of{ ident $self}; } @@ -244,6 +249,13 @@ sub _action { my ($self) = @_; return $action_of{ ident $self}; } sub _args { my ($self) = @_; return $args_of{ ident $self}; } + sub DESTROY { + my ($self) = @_; + my $ident = ident $self; + foreach my $attr_ref (@attr_refs) { + delete $attr_ref->{$ident}; + } + } } 1; # Magic true value required at end of module __END__