App-MergeCal
    
    
  
  
  
view release on metacpan or search on metacpan
bin/mergecal
Changes.md
lib/App/MergeCal.pm
Makefile.PL
MANIFEST
MANIFEST.SKIP
MYMETA.yml
pm_to_blib
t/00-load.t
t/01-basic.t
t/02-clean-calendars.t
t/pod.t
t/pod_coverage.t
META.yml                                 Module YAML meta-data (added by MakeMaker)
META.json                                Module JSON meta-data (added by MakeMaker)
lib/App/MergeCal.pm view on Meta::CPAN
=head1 NAME
App::MergeCal
=head1 ABSTRACT
Command line program that merges iCal files into a single calendar.
=head1 SYNOPSIS
    use App::MergeCal;
    my $app = App::MergeCal->new;
    $app->run;
    # Or, more likely, use the mergecal program
lib/App/MergeCal.pm view on Meta::CPAN
  use Encode 'encode_utf8';
  use Text::vFile::asData;
  use LWP::Simple;
  use JSON;
  use URI;
  field $vfile_parser :param = Text::vFile::asData->new;
  field $title :param;
  field $output :param = '';
  field $calendars :param;
  field $objects;
=head1 METHODS
=head2 $app->calendars, $app->title, $app->output
Accessors for fields.
=cut
  method calendars { return $calendars }
  method title     { return $title }
  method output    { return $title }
=head2 $app->run
Main driver method.
=cut
  method run {
    $self->gather;
    $self->render;
  }
=head2 $app->gather
Access all of the calendars and gather their contents into $objects.
=cut
  method gather {
    $self->clean_calendars;
    for (@$calendars) {
      my $ics = get($_) or die "Can't get " . $_->as_string . "\n";
      $ics = encode_utf8($ics);
      open my $fh, '<', \$ics or die $!;
      my $data = $vfile_parser->parse( $fh );
      push @$objects, @{ $data->{objects}[0]{objects} };
    }
  }
=head2 $app->render
lib/App/MergeCal.pm view on Meta::CPAN
    my $out_fh;
    if ($output) {
      open $out_fh, '>', $output
        or die "Cannot open output file [$output]: $!\n";
      select $out_fh;
    }
    say "$_\r" for Text::vFile::asData->generate_lines($combined);
  }
=head2 $app->clean_calendars
Ensure that all of the calendars are URIs. If a calendar doesn't have a scheme
then it is assumed to be a file URI.
=cut
  method clean_calendars {
    for (@$calendars) {
      $_ = URI->new($_) unless ref $_;
      if (! $_->scheme) {
        $_ = URI->new('file://' . $_);
      }
    }
  }
=head2 App::MergeCal->new, App::MergeCal->new_from_json, App::MergeCal->new_from_json_file
Constructor methods.
lib/App/MergeCal.pm view on Meta::CPAN
}
=head1 CONFIGURATION
The behaviour of the program is controlled by a JSON file. The default name
for this file is C<config.json>. The contents of the file will look something
like this:
    {
      "title":"My Combined Calendar",
      "output":"my_calendar.ics",
      "calendars":[
        "https://example.com/some_calendar.ics",
        "https://example.com/some_other_calendar.ics",
      ]
    }
This configuration will read the the calendars from the URLs listed and
combine their contents into a file called C<my_calendar.ics> (which you will
presumably make available on the internet).
The <output> configuration option is optional. If it is omitted, then the
output will be written to C<STDOUT>.
=head1 AUTHOR
Dave Cross <dave@perlhacks.com>
=head1 LICENSE
t/01-basic.t view on Meta::CPAN
use strict;
use warnings;
use Test::More;
use App::MergeCal;
ok(my $app = App::MergeCal->new(
  title     => 'Test',
  calendars => [
    'http://example.com/1.ics',
    'http://example.com/2.ics',
  ],
), 'Got an object');
isa_ok($app, 'App::MergeCal');
can_ok($app, qw[run gather render]);
is($app->calendars->@*, 2, 'Correct number of calendars');
is($app->title, 'Test', 'Correct title');
done_testing;
t/02-clean-calendars.t view on Meta::CPAN
use strict;
use warnings;
use Test::More;
use App::MergeCal;
my $app = App::MergeCal->new(
  title     => 'Test',
  calendars => [
    'http://example.com/1.ics',
    '2.ics',
  ],
);
$app->clean_calendars;
for ($app->calendars->@*) {
  isa_ok($_, 'URI');
}
is $app->calendars->[0]->scheme, 'http', 'First calendar is an HTTP URI';
is $app->calendars->[1]->scheme, 'file', 'Second calendar is a file URI';
done_testing;
( run in 0.798 second using v1.01-cache-2.11-cpan-5dc5da66d9d )