App-Toodledo

 view release on metacpan or  search on metacpan

lib/App/Toodledo.pm  view on Meta::CPAN

  my $ref = decode_json( $res->content )
    or $self->log->logdie( "Content invalid\n");

  $self->log->logdie( $ref->{errorCode} == 500 ? "Toodledo offline\n"
                                 : "Error: " . $ref->{errorDesc})
    if ref $ref eq 'HASH' && $ref->{errorCode};
  $ref;
}


method select ( ArrayRef[Object] $o_ref, Str $expr ) {
  my $prototype = $o_ref->[0] or return;

  # XXX CODE SMELL: refactor to polymorphic method
  if ( ref( $prototype ) =~ /task/i )
  {
    $expr =~ s/(.*)/($1) && completed == 0/ unless $expr =~ /completed/;
  }

  $expr =~ s/\b$_\b/\$self->$_/g for $prototype->attribute_list;
  $self->log->debug( "Searching in " . @$o_ref . "objects for '$expr'\n" );
  my $selector = sub { my $self = shift; eval $expr };
  $self->grep_objects( $o_ref, $selector );
}


method grep_objects ( ArrayRef[Object] $o_ref, CodeRef $selector ) {
  grep { $selector->( $_ ) } @$o_ref;
}


method foreach ( ArrayRef[Object] $o_ref, CodeRef $callback, @args ) {
  for ( @$o_ref )
  {
    $callback->( $_, @args );
    $App::Toodledo::Task::can_use_cache = 1;
  }
}


# @args here is just for testing purposes. If used for real code, will
# produce unexpected and erroneous results.
method get_tasks_with_cache ( @args ) {
  $self->task_cache_valid and return $self->task_cache->tasks;
  # -1 => Completed & uncompleted tasks
  my @tasks = $self->get( tasks => comp => -1, @args );
  $self->store_tasks_in_cache( @tasks );
  @tasks;
}


method task_cache_valid () {
  my $ai = $self->account_info;
  unless ( $self->task_cache )
  {
    $self->task_cache( App::Toodledo::TaskCache->new );
    return unless $self->task_cache->exists;
    $self->task_cache->fetch;
  }

  my $fetched = $self->task_cache->last_updated;
  my $logstr = "Edited: " . localtime( $ai->lastedit_task )
             . ", Deleted: " . localtime( $ai->lastdelete_task )
             . " Fetched: " . localtime( $fetched );
  if ( $ai->lastedit_task >= $fetched || $ai->lastdelete_task >= $fetched )
  {
    $self->log->debug( "Task cache invalid ($logstr)\n" );
    return;
  }
  $self->log->debug( "Task cache valid ($logstr)\n" );
  return 1;
}


method store_tasks_in_cache ( App::Toodledo::Task @tasks ) {
  $self->task_cache or $self->task_cache( App::Toodledo::TaskCache->new );
  $self->task_cache->store( @tasks );
}


# Add a new whatever
method add( Object $object! ) {
  $object->add( $self );
}


method edit ( Object $object, @more ) {
  $object->edit( $self, @more );
}


# Remove a whatever... it needs only have the id field populated
method delete( Object $object ) {
  $object->delete( $self );
}


method readable ( Object $object, Str $attribute ) {
  my $value = $object->$attribute;
  if ( $attribute =~ /date\z/ )
  {
    $value or return '';
    return preferred_date_format( $self->account_info->dateformat, $value );
  }
  $value;
}


1;

__END__

=head1 NAME

App::Toodledo - Interacting with the Toodledo task management service.

=head1 SYNOPSIS

    use App::Toodledo;

    my $todo = App::Toodledo->new( user_id => 'rudolph', app_id => 'MyAppID' );

lib/App/Toodledo.pm  view on Meta::CPAN

$token = $todo->new_session_token( $app_token )

Return the temporary session token given the application token.
The user_id and app_id are read from the object.

=head2 @objects = $todo->get( $type )

Fetch and return a list of some kind of thing, the choices being the following
strings:

=over 4

=item tasks

=item folders

=item goals

=item contexts

=item notebooks

=back

The returned list will be of the corresponding App::Toodledo::I<whatever>
objects.  There are optional arguments for tasks:

=head2 @tasks = $todo->get( tasks => %param )

The optional named parameters correspond to the parameters that can be
specified in the Toodledo tasks/get API call: modbefore, modafter,
comp, start, num, fields.  Note that this call will not cache the
tasks returned, so it is safe to play with these parameters.  This
method will default C<fields> to all available fields.  It does I<not>
change C<comp>, which the Toodledo API defaults to all uncompleted tasks
only.

=head2 @tasks = $todo->get_tasks_with_cache( %param )

Same as get( tasks => %param ), except that the tasks are fetched from
the cache file C<~/.toodledo_task_cache> if it is still valid (Toodledo
reports no changes since cache update).  If there is no cache file, it
is populated after the tasks are fetched from Toodledo.  This fetches
all tasks, including completed ones, so can take a while.

=head2 $id = $todo->add( $object )

The argument should be a new App::Toodledo::I<whatever> object to be created.
The result is the id of the new object. Any of the standard object types
can be added.
Note: this method is overridden in App::Toodledo::Task.

=head2 $todo->delete( $object )

Delete the given object from Toodledo. The C<id> attribute of the object
must be correctly set. No other attributes will be used.
Note: this method is overridden in App::Toodledo::Task.

=head2 $todo->edit( $object )

The given object will be updated in Toodledo to match the one passed.
Note: this method is overridden in App::Toodledo::Task.  When the object
is a task, the signature is:

=head2 $todo->edit( $task, [@tasks] )

All of the tasks will be edited.  You are responsible for ensuring
that you do not exceed Toodledo limits on the number of tasks passed
(currently 50).

=head2 @objects = $todo->select( \@objects, $expr );

Select just the objects you need from the given array, based upon the
expression.  Any attribute of the given objects specified in the exprssion
will br turned into an object accessor for that attribute and the resulting
expression must be syntactically correct.  Any Perl code can be used; it will
be passed through C<eval>.  Examples:

=over 4

=item tag eq "garden" && status > 3

Must have the 'garden' tag (and only that tag) amd a status greater
than the index for the status value 'Planning'.  (Only makes sense for
a task list.)  To access (or change) the status as a string,
use C<status_str>.

=item title =~ /deliver/i && comp == 1

Title must match regex and task must be completed.

=back

The type of object is determined from the first one in the arrayref.

=head2 @objects = $todo->grep_objects( \@objects, $coderef )

Run $coderef for each object in the list.  Called by the
C<select> method but can be used by the user.  Ones for which
the C<$coderef> returns true will be passed through to the result.

=head2 $todo->foreach( \@objects, $coderef, [@args] )

Run the coderef on each object in the arrayref.  C<$coderef>
will be called with the object as the first argument and
any C<@args> as the rest.

=head2 $todo->readable( $object, $attribute )

Currently just looks to see if the given C<$attribute> of C<$object>
is a date and if so, returns the C<preferred_date_formst> string
from L<App::Toodledo::Util> instead of the stored epoch second count.
If the date is null, returns an empty string (rather than the Toodledo
display of "no date").

=head1 ERRORS

Any API call may croak if it returns an error.

=head1 FILES



( run in 1.144 second using v1.01-cache-2.11-cpan-364913b4093 )