Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use feature qw/say/;
use open qw/:encoding(utf-8) :std/;
use JSON qw//;
use Time::Moment qw//;
use Google::API::Client;
use Google::API::OAuth2::Client;
use XML::Simple ();
use Cache::FileCache;
use DDP; # cpanm Data::Printer かしてね(最近だと cpm でも良い)
my $myemail = 'xxx@gmail.com';
my $client_secrets_file = 'client_secret.json';
my $client = Google::API::Client->new;
my $gcal = $client->build('calendar', 'v3');
my $auth_driver = Google::API::OAuth2::Client->new_from_client_secrets($client_secrets_file, $gcal->{auth_doc});
my $dat_file = 'token.dat';
get_or_restore_token($dat_file, $auth_driver);
my $my_calender_id = 'primary';
my $holiday_calendar_id = 'ja.japanese#holiday@group.v.calendar.google.com';
my $cache = Cache::FileCache->new({
cache_root => '/tmp',
namespace => 'calendar',
});
my %cache_duration_of = (
$my_calender_id => '5s',
$holiday_calendar_id => '7d',
);
my $now = Time::Moment->now;
my $first_day_of_month = Time::Moment->new(
year => $now->year,
month => $now->month,
day => 1,
offset => 540, # +09:00(540分)
);
my $req_body = {
timeMax => $first_day_of_month->plus_months(6)->to_string,
timeMin => $first_day_of_month->minus_months(6)->to_string,
};
my $schedule = get_or_cache_event_items($my_calender_id);
my $holidays = get_or_cache_event_items($holiday_calendar_id);
my @events = (@{$schedule->{items}}, @{$holidays->{items}});
print make_xml(\@events);
exit;
sub get_or_restore_token
{
my ($file, $auth_driver) = @_;
if (-f $file)
{
open (my $fh, '<', $file) or die $!;
local $/;
my $access_token = JSON::from_json(<$fh>);
close($fh);
$auth_driver->token_obj($access_token);
}
else
{
my $auth_url = $auth_driver->authorize_uri;
say 'Go to the following link in your browser:';
say $auth_url;
say 'Enter verification code:';
chomp(my $code = <>);
$auth_driver->exchange($code);
store_token($file, $auth_driver);
}
}
sub store_token
{
my ($file, $auth_driver) = @_;
my $access_token = $auth_driver->token_obj;
open (my $fh, '>', $file) or die $!;
print {$fh} JSON::to_json($access_token);
close($fh);
}
sub get_or_cache_event_items
{
my $calendar_id = shift;
my $items = $cache->get($calendar_id);
if ( ! $items )
{
$items = $gcal->events->list(calendarId => $calendar_id, body => $req_body)->execute({ auth_driver => $auth_driver });
$cache->set($calendar_id => $items, $cache_duration_of{$calendar_id}) if $items;
}
return $items;
}
sub get_date_using_datetime { local $_ = $_[0]; s/(.+)T.+/$1/; $_; }
sub get_time_using_datetime { local $_ = $_[0]; s/.+T([0-9][0-9]:[0-9][0-9]):[0-9][0-9]\+.+/$1/; $_; }
sub make_xml
{
my $items = shift;
my $data = {};
$data->{event} = ();
my $i = 0;
for my $item (@{$items})
{
my $event = {};
my $startdate = $item->{start}{date} ? $item->{start}{date} : get_date_using_datetime($item->{start}{dateTime});
my $enddate = $item->{end}{date} ? $item->{end}{date} : get_date_using_datetime($item->{end}{dateTime});
$event->{id} = ++$i;
$event->{name} = $item->{summary};
$event->{startdate} = $startdate;
$event->{enddate} = $enddate;
$event->{color} = '#ffb128';
$event->{color} = '#ddeeff' if $item->{organizer}{email} ne $myemail;
$event->{starttime} = get_time_using_datetime($item->{start}{dateTime}) if $item->{start}{dateTime};
$event->{endtime} = get_time_using_datetime($item->{end}{dateTime}) if $item->{end}{dateTime};
push(@{$data->{event}}, $event);
}
return XML::Simple::XMLout($data, RootName => 'monthly', XMLDecl => '<?xml version="1.0"?>', NoAttr => 1);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.