Roundcube Community Forum

 

"Accept" vcal events (to google calendar) - Prototype (unsupported)

Started by Naatan85, April 13, 2010, 12:56:45 PM

Previous topic - Next topic

Naatan85

Hi guys,

I just installed roundcube on my work pc a while ago cause I was getting sick of Thunderbird using 100mb+ memory and could not find a decent alternative. I have it setup to check exchange mail through imap but unfortunately it does not integrate with meeting invitations.

So I made a very simple plugin that will detect vcal elements in e-mails and show a "Add to google calendar" link at the bottom of the e-mail.

Note that this should really be considered a prototype, I am absolutely certain there are better ways to go about this but I just wanted something simple that would work for me. I am sharing this so that someone that does have the time can pick it up and turn it into something nice.

To install create a folder called vcal_gcal in your plugins folder and create a new file inside it called vcal_gcal.php with the following contents:

<?php

/**
 * "Accept" vcal events and send them to google calendar
 *
 * @version 0.1 Alpha
 * @author Nathan Rijksen
 * @website http://roundcube.net
 */
class vcal_gcal extends rcube_plugin {
public $task 'mail';
private $event null;
private $subject 'Generic';

function init() {
$this->task 'mail';
$this->add_hook('message_load', array($this'scan'));
$this->add_hook('message_part_after', array($this'put'));

$this->register_action('plugin.gcal_vcal', array($this'request_handler'));
}

function scan($msg) {
$c 1;
$content true;

while ($content!=null) {
$content $msg['object']->get_part_content($c);

if (preg_match('/\<title\>(.*?)\<\/title\>/is',$content,$match)) 
$this->subject $match[1];

if (strripos($content,'BEGIN:VCALENDAR')!==false)
$this->parse_event($content);
$c++;
}
}

function put($args) {
if ($this->event==null)
return null;

$data = array();
$data['body'] = strip_tags($args['body']);
if (strlen($data['body'])>1000)
$data['body'] = substr($data['body'],0,1000).' [...]';

$data['subject'] = $this->subject;
$data['start'] = $this->event['DTSTARTTZID'];
$data['end'] = $this->event['DTENDTZID'];

$data strtr(base64_encode(addslashes(gzcompress(serialize($data),9))), '+/=''-_,');

$args['body'] .= '<p><a href=./?_task=mail&_action=plugin.gcal_vcal&data='.$data.'">Add this event to google calendar</a></p>';

return $args;
}
  
function parse_event($vcal_raw) {
$vcal_bits explode("\n",$vcal_raw);
$event = array();

foreach ($vcal_bits AS $bit) {
$bit_e explode(':',$bit);

if (count($bit_e)<2)
continue;

$bit_e[0] = str_replace(';','',$bit_e[0]);
$bit_e[0] = preg_replace('/([a-z]+).*/is','$1',$bit_e[0]);

$event[$bit_e[0]] = $bit_e[1];
}

$this->event $event;
}

function request_handler() {
$data unserialize(gzuncompress(stripslashes(base64_decode(strtr($_GET['data'], '-_,''+/=')))));

if ($data==false) return false;

$date_start strtotime($data['start']);
$date_end strtotime($data['end']);

$startDate date('Y-m-d',$date_start);
$startTime date('H:i',$date_start);
$endDate date('Y-m-d',$date_end);
$endTime date('H:i',$date_end);
$tzOffset '-05';

$subject $data['subject'];
$body $data['body'];

// Zend SUCKS - thanks google for forcing me to use this ..
$old_inc get_include_path();
set_include_path(dirname(__FILE__));

require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Gdata_AuthSub');
Zend_Loader::loadClass('Zend_Gdata_ClientLogin');
Zend_Loader::loadClass('Zend_Gdata_Calendar');

if (!isset($_GET['token'])) 
return $this->login_google();

$token Zend_Gdata_AuthSub::getAuthSubSessionToken($_GET['token']);
$client Zend_Gdata_AuthSub::getHttpClient($token);

$gdataCal = new Zend_Gdata_Calendar($client);
$newEvent $gdataCal->newEventEntry();

$newEvent->title $gdataCal->newTitle($subject);
$newEvent->content $gdataCal->newContent($body);

$when $gdataCal->newWhen();

$when->startTime "{$startDate}T{$startTime}:00.000{$tzOffset}:00";
$when->endTime "{$endDate}T{$endTime}:00.000{$tzOffset}:00";

$newEvent->when = array($when);

// Upload the event to the calendar server
// A copy of the event as it is recorded on the server is returned
$createdEvent $gdataCal->insertEvent($newEvent);

set_include_path($old_inc);

die('Added to calendar');
}

function login_google() {
$next $this->getCurrentUrl();
$scope 'http://www.google.com/calendar/feeds/';
$secure false;
$session true;
$url Zend_Gdata_AuthSub::getAuthSubTokenUri($next$scope$secure
$session);
header('Location: '.$url);
}

function getCurrentUrl() {
$pageURL 'http';
if ($_SERVER["HTTPS] == "on") {$pageURL .= "s";}
$pageURL .= "://";
if ($_SERVER["SERVER_PORT"] != "80") {
$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
} else {
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
return $pageURL;
}

}


Then create a folder inside vcal_gcal and call it Zedge. Download the following: Zend Framework: Downloads: Downloads. Extract in the Zedge folder.

Enable the plugin and you're done (note that it won't work for e-mails that have been cached prior to this plugin being enabled).

Again this is a very simplistic script that does exactly what it had to do for me to be usable and is by no means production ready.. I am just sharing it so that other devs may benefit from it.