Author Topic: "Accept" vcal events (to google calendar) - Prototype (unsupported)  (Read 6779 times)

Offline Naatan85

  • Newbie
  • *
  • Posts: 1
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.