#!/usr/bin/perl -w
use 5.010;
use strict;
use warnings;
use autodie;
use utf8::all;
# ABSTRACT: Command line interface to idonethis.com
our $VERSION = '0.22'; # VERSION: Generated by DZP::OurPkg::Version
# PODNAME: idone
use Getopt::Std;
use Pod::Usage;
use WebService::Idonethis;
use Config::Tiny;
use POSIX qw(tzset strftime);
use Date::Manip::Date;
use constant ONE_DAY => 86400; # Seconds in a day
# Make Getopt less wrong.
$Getopt::Std::STANDARD_HELP_VERSION = 1;
sub VERSION_MESSAGE { pod2usage(1); }
my %opts = (
'c' => undef, # STDIN
'd' => undef, # Date
'f' => "$ENV{HOME}/.idonethisrc", # Config
'h' => undef, # Help
'l' => undef, # List
'r' => undef, # Range
'V' => undef, # Version
'y' => undef, # Yesterday
);
getopts('cd:f:hlr:Vy', \%opts);
if ($opts{h}) {
pod2usage(1);
}
if ($opts{V}) {
say "idone version " , WebService::Idonethis->VERSION;
exit 1;
}
my $config = Config::Tiny->read( $opts{f} );
unless ($config->{auth}{user}) {
die "Cannot find credentials in $opts{f}\n";
}
my $idt = WebService::Idonethis->new(
user => $config->{auth}{user},
pass => $config->{auth}{pass},
calendar => $config->{auth}{calendar}
);
# Range processing
# BUG: If '-r' is provided with no argument, this doesn't seem
# to trigger. So don't do that.
if ($opts{r}) {
if ( $opts{d} or $opts{y} or $opts{c} ) {
die "-r cannot be used with either -d, -y or -c\n";
}
if (@ARGV) {
die "Items cannot be added to idone with C<-r>\n";
}
my ($from, $to) = split(/\s*,\s*/, $opts{r});
$to ||= 'now';
unless ($from) {
die "At least a start date is required for -r\n";
}
$from = parse_date($from);
$to = parse_date($to);
my $dones = $idt->get_range($from, $to);
# Results seem to come back in reverse chronological order,
# so we reverse them here.
foreach my $item (reverse @$dones) {
say "[$item->{done_date}] $item->{text}";
}
exit 0;
}
my $date = parse_date( $opts{d} || strftime("%Y-%m-%d",localtime()) );
# Handle yesterday if '-y' switch is turned on.
if ($opts{y}) {
$date = strftime("%Y-%m-%d", localtime(time() - ONE_DAY));
}
# If we've been given an argument, insert that as a done.
if (@ARGV) {
$idt->set_done( text => "@ARGV", date => $date );
}
elsif (not $opts{l}) {
# No arguments, and no -l implies -c
$opts{c} = 1;
}
# List items, if required.
if ($opts{l}) {
my $dones = $idt->get_day($date);
say "\nDone tasks for $date:\n";
foreach my $item (@$dones) {
say "* $item->{text}";
}
}
# Read items, if requested.
if ($opts{c}) {
say "\nReading done items for $date (one per line).\n";
while (<STDIN>) {
chomp;
$idt->set_done( text => $_, date => $date );
}
}
sub parse_date {
my ($date) = @_;
if ($date !~ /^\d{4}-\d{2}-\d{2}$/) {
my $dmd = Date::Manip::Date->new;
if ($dmd->parse($date)) {
die "Can't parse date '$date' - " . $dmd->err . "\n";
}
$date = $dmd->printf("%Y-%m-%d");
}
return $date;
}
__END__
=pod
=head1 NAME
idone - Command line interface to idonethis.com
=head1 VERSION
version 0.22
=head1 SYNOPSIS
# Submit an item to idonethis.com
$ idone "Installed some cool software today."
# See what I've done today.
$ idone -l
# Add an item to idonethis, and then show everything I've done
$ idone -l "Calibrated the flux capacitor"
# See what I've done yesterday.
$ idone -ly
# See what I did some time ago.
$ idone -ld 2012-01-01
# See what I've done today, and read new items from STDIN.
$ idone -lc
# See what I've done yesterday, and add more items from STDIN.
$ idone -lcy
# See what I've done in the last week
$ idone -lr 'last week,today'
# In ~/.idonethisrc
[auth]
user=someuser
pass=somepass
calendar=some calendar name
=head1 DESCRIPTION
By default, this submits items to your personal calendar on idonethis. All
arguments are concatenated together to form a single string, which
is then submitted to your calendar for the current day (using the
local timezone on your machine).
The C<calendar> name is optional, and if present will be searched
for in first the URL, then as a text link. If not found, your username
will be used, and if all else fails, idone will default to your
personal calendar.
Patches are extremely welcome. L<https://github.com/pjf/idonethis-perl>
=head1 OPTIONS
=over
=item B<-c>
Read items from STDIN and add them to your done list, with one item per
line. This is the default behaviour if C<-l> is not specified, nor any
done item on the command line.
=item B<-d date>
Specify the date upon which actions should be taken. Any date that can
be understood by L<Date::Manip::Date> can be used, including strings such
as 'last Tuesday' or 'three days ago'.
If in doubt, use YYYY-MM-DD format.
Defaults to today. This switch is silently ignored if used with C<-y>.
=item B<-f config>
Specify the location of the configuration file. Defaults to ~/.idonethisrc
=item B<-h>
Displays this help.
=item B<-l>
List items that you've done. Combine this with the C<-c> switch
to list done items, and let you add new ones to the end.
=item B<-r>
List items in a I<range> of dates, in the form C<-r '2013-01-01, 2013-01-31'>.
Natural dates may also be used, as in C<-r '1 week ago, today'>. This switch
is exclusive of the C<-d>, C<-y> and C<-c> switches.
With only a single argument, a second argument of 'now' is implied. This
allows shortcuts like C<idone -r'last week'> to show everything done
since last week.
This switch implies C<-l>.
=item B<-V>
Shows the current version and exits.
=item B<-y>
Perform all operations (adding and listing) using yesterday's date.
This switch overrides the C<-d> switch, if given.
=back
=head1 AUTHOR
Paul Fenwick <pjf@cpan.org>
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2013 by Paul Fenwick.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut