
| Current Path : /var/www/web-klick.de/dsh/90_akt/appserv/DivBasicF/ |
Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 |
| Current File : /var/www/web-klick.de/dsh/90_akt/appserv/DivBasicF/GoogleCal.pm |
package DivBasicF::GoogleCal;
# Dieses Paket ist eine API fuer den Google-Kalender.
use strict;
use LWP::UserAgent;
use Server::frezthaw;
use MIME::Base64;
use Data::Dumper;
# code.google.com/apis/calendar/developers_guide_protocol.html
#******************************************************************
# new nimmt als Parameter ein Array, das in einen Hash umgewandelt wird.
# Die Form ist:
# <kalender-identifier1> => <google-kalender-adresse1>,
# <kalender-identifier2> => <google-kalender-adresse2>
#
# Mit diesem Hash koennen die Kalender auch ueber die
# jeweiligen selbstgewaehlten Kalender-Identifier angesprochen werden.
#
# Die Kalender koennen aber auch direkt ueber die jeweilige
# Google-Kalender-Adresse angesprochen werden.
sub new {
my $class = shift;
my $self = {};
$self->{'CALS'} = {@_};
$self->{'AUTH'} = "";
$self->{'UA'} = LWP::UserAgent->new();
$self->{'BATCH'} = [];
$self->{'MONATE'} = { JA => 1, FE => 2, MR => 3, AP => 4,
MA => 2, JN => 6, JL => 7, AU => 8,
SE => 3, OC => 10, NO => 11, DE => 12 };
bless($self,$class);
return($self);
}
#******************************************************************
sub monate {
my $self = shift;
my $monat = shift;
return($self->{'MONATE'}->{$monat});
}
#******************************************************************
# Diese Funktion muss aufgerufen werden, um eine Authentifizierung
# fuer die Google Datenbank zu bekommen. Mit dieser Authenfizierung
# werden dann Kalenderfunktionen aufrufbar.
sub auth {
my $self = shift;
my $user = shift;
my $password = shift;
my $c=5; # 5 Versuche, sich einzuloggen
my $o;
# while (0 == 0) { # sonst bleibt es bei ungueltigen Logins in der Endlosschleife drin
while ($c > 0) {
$c = $c - 1;
$o = $self->{'UA'}->post("https://www.google.com/accounts/ClientLogin", {
"Email" => $user,
"Passwd" => $password,
"source" => "ift-googlecal-02",
"service" => "cl"
})->content();
$o =~ /Auth\=(.*)/;
$self->{'UA'}->default_header("Authorization","GoogleLogin auth=".$1);
$self->{'AUTH'} = $1;
last if ($self->{'AUTH'});
}
return($self->{'AUTH'});
}
#***********************************************************************
# Hilfsfunktion
sub att_mail {
my $self = shift;
my $o = shift;
my $attendee = "";
my $email = "";
if ($o =~ /^(.*)\:(.*)$/) {
$attendee = $1;
$email = $2;
}
elsif ($o =~ /\@/) {
$email = $o;
}
else {
$attendee = $o;
}
if ($email =~ /^(.*)\=(.*)$/) {
$email = [$1,$2];
}
return($attendee,$email);
}
#******************************************************************
# Liefert eine Liste aller verfuegbaren Kalender
sub calendarlist {
my $self = shift;
return( $self->{'UA'}->get(
# "http://www.google.com/calendar/feeds/default/allcalendars/full"
"http://www.google.com/calendar/feeds/default/private/full"
)->content() );
}
#******************************************************************
# Hilfsfunktion. Fuehrt XML-Befehle aus.
sub exec_cmd {
my $self = shift;
my $method = shift;
my $feed = shift;
my $cmd = shift;
my $o;
if ($feed) {
push(@{$self->{'BATCH'}},[$method,$feed,$cmd]);
$o = $self->exec_cmd();
return($o->[0]);
} else {
my $o;
my $header; my $uri; my $request; my $response; my $text;
my @ee = @{$self->{'BATCH'}};
$self->{'BATCH'} = [];
my $erg = [];
while (@ee) {
$o = shift(@ee);
$method = $o->[0];
$feed = $o->[1];
$cmd = $o->[2];
$header = HTTP::Headers->new('Content-Type' => 'application/atom+xml');
$uri = "http://www.google.com/calendar/feeds/" . $feed;
$request = HTTP::Request->new($method,$uri,$header,$cmd);
$response = $self->{'UA'}->request($request);
$text = $response->content();
if ($text =~ /The document has moved(.*?)\"(.*?)\"\>here/) {
$uri = $2;
$request = HTTP::Request->new($method,$uri,$header,$cmd);
$response = $self->{'UA'}->request($request);
$text = $response->content();
}
push(@$erg,$text);
}
return($erg);
}
}
#***************************************************************************
# Liefert eine Liste von Kalender-Eintraegen.
# Abfragemoeglichkeiten alternativ:
#
# 1. $calendar: Kalender, der abgefragt wird
# 2. $query: Zeitintervall im Format:
# JJJJMMDD-JJJJMMDD
#
#
# 1. $calendar: Kalender, der abgefragt wird
# 2. query: <pattern>. Alle Kalender-Eintraege, die <pattern> enthalten,
# werden herausgegegen.
#
#
# Jeder gefundene Kalender-Eintrag $entry ist ein anonymer Hash, der
# folgende Felder hat:
#
# $entry->{'___'}: Kompletter XML-String des Kalender-Eintrags
# $entry->{'ID'}: Identifier des Kalender-Eintrags
# $entry->{'REV'}: Revisisonsnummer des Kalender-Eintrags
# $entry->{'IDR'}: $entry->{'ID'} . "/" . $entry->{'REV'}
# $entry->{'CALENDAR'}: Zugehoeriger Kalender
# $entry->{'CIDR'}: $entry->{'CALENDAR'} . "/" . $entry->{'ID'} . "/" .
# $entry->{'REV'}
# $entry->{'TITLE'}: Titel
# $entry->{'CONTENT'}: Content-Feld
# $entry->{'STARTTIME'}: Startzeitpunkt
# $entry->{'ENDTIME'}: Ende-Zeitpunkt
# $entry->{'STARTDAY'}: Tag des Startzeitpunktes
# $entry->{'ENDDAY'}: Tag des Ende-Zeitpunktes
# $entry->{'A'}: Uhrzeit des Startzeitpunktes
# $entry->{'E'}: Uhrzeit des Ende-Zeitpunktes
# $entry->{'TRANSPARENCY'}: Transparenz
# $entry->{'WHERE'}: Ort
# $entry->{'EVENTSTATUS'}: Status des Kalender-Eintrags
# $entry->{'ATTENDEE'}: Hash, der als Schluessel alle Teilnehmer
# des Kalendereintrags enthaelt. Jeweiliger
# Wert zu jedem Schluessel ist ein String,
# bestehend aus Eintraegen der Form:
# JJMMDD_HHMM<x>, wobei x ein Buchstabe ist:
# i: invited (eingeladen)
# a: accepted (angenommen)
# t: tentative (vielleicht)
# d: declined (abgelehnt)
# Damit wird die Historie der Annahme bzw.
# Ablehnung des Termins seitens des Teilnehmers
# wiedergegeben.
# $entry->{'ATTENDEE'}->{'___INFO___'}: Spezialfeld, dessen Inhalt,
# in eckige Klammern gesetzt, an $entry->{'CONTENT'}
# drangehaengt wird. Diese Angabe in Klammern
# ist im Google-Kalender verschluesselt und
# kann nicht per Browser eingesehen werden.
sub find_entry {
my $self = shift;
my $calendar = shift;
my $query = shift;
my $endtime = shift;
my $xml; my $o; my $o1; my $o2; my $o3; my $o8; my $o9;
my $akt_date = $self->akt_date();
if ($endtime) {
$xml = $self->exec_cmd("GET",$calendar."/private/full?start-min=".
$query . "\&start-max=" . $endtime .
"\&orderby=starttime\&max-results=999999");
}
elsif ($query =~ /^(\d\d\d\d)(\d\d)(\d\d)\-(\d\d\d\d)(\d\d)(\d\d)$/) {
$o = "$1-$2-$3T00:00:00";
$o1 = "$4-$5-$6T23:59:00";
$xml = $self->exec_cmd("GET",$calendar."/private/full?start-min=".
$o . "\&start-max=" . $o1 .
"\&orderby=starttime\&max-results=999999");
}
# elsif ($query =~ /^ID\:(.*)$/) { # ID Query
# $xml = $self->exec_cmd("GET",$calendar."/private/full/".$1);
# }
else { # Full Text Query
$xml = $self->exec_cmd("POST",$calendar."/private/full?q=".$query);
}
my $erg = [];
while ($xml =~ s/(\<entry\>.*?\<\/entry\>)//s) {
$o = { "___" => $1 } ;
$o1 = $o->{'___'};
$o->{'CALENDAR'} = $calendar;
if ($o1 =~ /\/private\/full\/([\_a-zA-Z0-9]+)\/([0-9]+)/s) {
$o->{'ID'} = $1;
$o->{'REV'} = $2;
$o->{'IDR'} = $o->{'ID'} . "\/" . $o->{'REV'};
$o->{'CIDR'} = $o->{'CALENDAR'} . "\;" . $o->{'IDR'};
}
if ($o1 =~ /\<title\s.*?\>(.*?)\<\/title\>/s) {
$o->{'TITLE'} = $1;
}
if ($o1 =~ /\<content\s.*?\>(.*?)\<\/content\>/s) {
$o->{'CONTENT'} = $1;
}
$o->{'ATTENDEE'} = {};
if ($o->{'CONTENT'} =~ s/\{(.*)\}//s) {
$o3 = $1;
$o3 =~ s/\n//gs;
$o->{'ATTENDEE'} = (Server::frezthaw::thaw(
unpack('u',MIME::Base64::decode_base64($o3))))[0];
$o->{'CONTENT'} =~ s/^[ \n]*(.*?)[ \n]$/$1/s;
if ($o->{'ATTENDEE'}->{'___INFO___'}) {
$o3 = "[" . $o->{'ATTENDEE'}->{'___INFO___'} . "]";
delete ($o->{'ATTENDEE'}->{'___INFO___'});
if ($o->{'CONTENT'} !~ s/\[\]/$o3/s) {
$o->{'CONTENT'} = $o->{'CONTENT'} . "\n" . $o3;
}
}
}
# print "DD: " . Dumper($o->{'ATTENDEE'}) . "\n"; sleep 5;
if ($o1 =~ /\<gd\:transparency\s.*?event\.(.*?)[\'\"]/s) {
$o->{'TRANSPARENCY'} = $1;
}
if ($o1 =~ /\<gd\:eventStatus\s.*?event\.(.*?)[\'\"]/s) {
$o->{'EVENTSTATUS'} = $1;
}
if ($o1 =~ /\<gd\:where\s.*?[\'\"](.*?)[\'\"]/s) {
$o->{'WHERE'} = $1;
}
if ($o1 =~ /startTime=[\'\"]([0-9\-]+)[\'\"]/s) {
# print "AA: $1\n"; sleep 2;
$o->{'STARTTIME'} = $1 . "T00:01:00";
}
elsif ($o1 =~ /startTime=[\'\"](.*?)\.(.*?)[\'\"]/s) {
# print "YY: $1\n"; sleep 2;
$o->{'STARTTIME'} = $1;
}
if ($o1 =~ /endTime=[\'\"]([0-9\-]+)[\'\"]/s) {
$o->{'ENDTIME'} = $1 . "T23:59:00";
}
elsif ($o1 =~ /endTime=[\'\"](.*?)\.(.*?)[\'\"]/s) {
$o->{'ENDTIME'} = $1;
}
my $ee1 = {};
my $o99 = $o1;
while ($o1 =~ s/^(.*)\<gd\:who\s(.*?\s?)email=[\"\'](.*?)[\"\'](.*?)(\<\/gd\:who\>|\/\>)/$1/s) {
$o8 = $2 . $4;
$o9 = $3;
$ee1->{$o9} = 1;
$o8 =~ s/event\.attendee//;
if ($o8 =~ s/event\.organizer//) {
$o2 = "organizer";
if ($o8 =~ /event\.([a-z]+)/) {
$o2 = uc($1);
}
$o2 = "organizer";
} else {
$o8 =~ /event\.([a-z]+)/;
$o2 = $1;
}
if ($o8 =~ /organizer/) {
$o2 = "organizer";
}
$o2 = substr($o2,0,1);
if (!($o->{'ATTENDEE'}->{$o9})) {
$o->{'ATTENDEE'}->{$o9} = $akt_date . $o2;
}
$o3 = "";
if ($o->{'ATTENDEE'}->{$o9} =~ /([atidoATID])$/) {
$o3 = $1;
}
if ($o3 ne $o2) {
if ($o3) { $o3 = ","; }
$o->{'ATTENDEE'}->{$o9} = $o->{'ATTENDEE'}->{$o9} .
$o3 . $akt_date . $o2;
$o->{'NEW'} = 1;
}
}
foreach $o9 (sort keys %$ee1) {
$ee1->{$o9} = $o->{'ATTENDEE'}->{$o9};
}
$o->{'ATTENDEE'} = $ee1;
if ($o->{'STARTTIME'} =~ /^(.*)T(.*)\:00$/) {
$o->{'STARTDAY'} = $1;
$o->{'A'} = $2;
}
if ($o->{'ENDTIME'} =~ /^(.*)T(.*)\:00$/) {
$o->{'ENDDAY'} = $1;
$o->{'E'} = $2;
}
$o->{'HOME'} = $calendar;
if ($o->{'ATTENDEE'}->{$o->{'HOME'}} =~ /o/) {
delete($o->{'ATTENDEE'}->{$o->{'HOME'}});
} else {
delete($o->{'NEW'});
}
push(@$erg,$o);
}
return($erg);
}
#**************************************************************************
# Hilfsfunktion
sub akt_date {
my $self = shift;
my $akt_date = time();
$akt_date = sprintf("%02u",(localtime($akt_date))[5]-100) .
sprintf("%02u",(localtime($akt_date))[4]+1) .
sprintf("%02u",(localtime($akt_date))[3]) . "_" .
sprintf("%02u",(localtime($akt_date))[2]) .
sprintf("%02u",(localtime($akt_date))[1]);
return($akt_date);
}
#************************************************************************
# Hilfsfunktion
sub encode {
my $self = shift;
my $obj = shift;
$obj = MIME::Base64::encode_base64(pack('u',Server::frezthaw::freeze(
$obj)));
my $o; my $text = "";
foreach $o (split(/\n/,$obj)) {
if ($o =~ /^(....................................)(.+?)$/) {
$text = $text . $1 . "\n" . $2 . "\n";
} else {
$text = $text . $o . "\n";
}
}
return($text);
}
#**************************************************************************
# Erstellt einen neuen Kalender-Eintrag
sub create_entry {
my $self = shift;
my $calendar = shift; # Kalender
my $title = shift; # Titel
my $content = shift; # Inhalt
# Wenn $content einen Text in
# eckigen Klammern enthaelt, dann wird dieser
# entfernt und verschluesselt abgespeichert
my $where = shift; # Ort
my $start = shift; # Beginn des Termins: <jjjj-mm-tt>T<hh:mm:ss>
my $end = shift; # Ende des Termins: <jjjj-mm-tt>T<hh:mm:ss>
my $notificate = shift; # Wenn 1, Teilnehmer per Mail benachrichtigen
# wenn 0, Teilnehmer nicht benachrichtigen
my @ee = @_; # Teilnehmerliste(n), kommasepariert
# Hier kann auch der jeweilige Alias
# (siehe unter new) angegeben werden.
my $akt_date = $self->akt_date();
my $attendees = {};
if ($content =~ s/\[(.*?)\]/\[\]/s) {
$attendees->{'___INFO___'} = $1;
}
my $o; my $attendee; my $email; my $text;
my @who = ();
foreach $o (@ee) {
$o =~ s/,/\n/gs;
foreach $text (split(/\n/,$o)) {
next if (!$text);
push(@who,$text);
}
}
my $xml = <<'TEXT_ENDE';
<entry xmlns='http://www.w3.org/2005/Atom'
xmlns:gd='http://schemas.google.com/g/2005'
xmlns:gCal='http://schemas.google.com/gCal/2005'>
<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event' />
<gCal:sendEventNotifications value="---NOTIF---"/>
<title type='text'>---TITLE---</title>
<content type='---TEXT---'>---CONTENT---</content>
<gd:transparency
value='http://schemas.google.com/g/2005#event.opaque'>
</gd:transparency>
<gd:eventStatus
value='http://schemas.google.com/g/2005#event.confirmed'>
</gd:eventStatus>
<gd:where valueString='---WHERE---'></gd:where>
<gd:when startTime='---START---' endTime='---END---'></gd:when>
TEXT_ENDE
if ($notificate) { $o = "true"; } else { $o = "false"; }
$xml =~ s/---NOTIF---/$o/;
$xml =~ s/---TITLE---/$title/;
$xml =~ s/---WHERE---/$where/;
$xml =~ s/---START---/$start/;
$xml =~ s/---END---/$end/;
while (@who) {
$o = shift(@who);
($attendee,$email) = $self->att_mail($o);
if (ref($email)) { $email = $email->[0]; }
$text = <<'TEXT_ENDE';
<gd:who rel="http://schemas.google.com/g/2005#event.attendee"
valueString="---ATTENDEE---" email="---EMAIL---">
<gd:attendeeStatus value="http://schemas.google.com/g/2005#event.invited"/>
</gd:who>
TEXT_ENDE
$text =~ s/---ATTENDEE---/$attendee/;
$text =~ s/---EMAIL---/$email/;
$attendees->{$email} = $akt_date . "i";
$xml = $xml . $text;
}
if ($content) {
$content = $content . "\n";
}
if (%$attendees and $title !~ /^ *\./) {
$content = $content . "\n\{" . $self->encode($attendees);
$content =~ s/\n$//s;
$content = $content . "\}";
}
$xml =~ s/---TEXT---/text/;
$xml =~ s/---CONTENT---/$content/;
$xml = $xml . "</entry>\n";
while ($xml =~ s/\n *\n/\n/gs) { 1; }
# print "UIU: $xml\n";
$xml = $self->exec_cmd("POST",$calendar."/private/full",$xml);
if ($xml =~ /\/private\/full\/([\_a-zA-Z0-9]+)\/([0-9]+)/) { # Rueckgabe: Event-ID
$xml = $1 . "\/" . $2;
}
return($xml);
}
#***************************************************************************
# Diese Funktion schreibt einen geaenderten Kalender-Eintrag
# in die Google-Datenbank. Eine Meldung an die Teilnehmer geht nur
# dann raus, wenn sich der Titel oder der Textteil in Content,
# der nicht in eckige Klammern eingeschlosen ist, oder Start- bzw.
# Ende-Zeitpunkt geaendert haben.
sub update_entry {
my $self = shift;
my $entry = shift;
my $notificate = shift; # Wenn 1, Teilnehmer benachrichtigen.
# Kann durch $entry->{'NO_NOTIFY'}
# ueberschrieben werden
# $notificate = 0;
my @ee = @_;
return("NOT CHANGED") if (!($entry->{'CHANGED'}));
# $notificate = 0;
my $notificate1 = $notificate;
my $calendar = $entry->{'CALENDAR'};
if ($entry->{'NO_NOTIFY'}) {
$notificate = 0;
delete ($entry->{'NO_NOTIFY'});
}
my $o1 = $entry->{'___INTERMEDIATE___'};
if (!$o1) {
$o1 = $entry->{'___'};
} else {
$notificate = 0;
}
my $o2 = <<'TEXT_ENDE';
<entry xmlns='http://www.w3.org/2005/Atom'
xmlns:gd='http://schemas.google.com/g/2005'
xmlns:gCal="http://schemas.google.com/gCal/2005">
<category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/g/2005#event' />
<gCal:sendEventNotifications value="---NOTIF---"/>
TEXT_ENDE
$o1 =~ s/(\<entry\>)/$o2/;
# $entry->{'___'} =~ s/_n_/___NOT_SEND___/;
# if ($entry->{'___'} =~ s/___NOT_SEND___//) { $o2 = "false"; }
if ($notificate) { $o2 = "true"; } else { $o2 = "false"; }
$o1 =~ s/---NOTIF---/$o2/;
$o1 = $self->exec_cmd("PUT",$calendar."/private/full/".$entry->{'IDR'},$o1);
print substr($o1,0,200) . "\n===NOTIFICATE: $o2\n";
if ($o1 =~ /\/private\/full\/([\_a-zA-Z0-9]+)\/([0-9]+)/) { # Rueckgabe: Event-ID
$entry->{'ID'} = $1;
$entry->{'REV'} = $2;
$entry->{'IDR'} = $entry->{'ID'} . "\/" . $entry->{'REV'};
$entry->{'CIDR'} = $calendar . "\;" . $entry->{'ID'};
}
if ($entry->{'___INTERMEDIATE___'}) {
delete ($entry->{'___INTERMEDIATE___'});
return( $self->update_entry($entry,$notificate1) );
} else {
return($o1);
}
}
#***************************************************************************
# Diese Funktion loescht einen Kalender-Eintrag aus der Google-Datenbank
sub delete_entry {
my $self = shift;
my $entry = shift;
my $notificate = shift;
my @ee = @_;
return(0) if ($entry->{'ATTENDEE'}->{$entry->{'HOME'}});
my $calendar = $entry->{'CALENDAR'};
if ($notificate) {
if ($self->change_entry($entry,"SUBTRACT","ALL")) {
$self->update_entry($entry,1);
}
}
return($self->exec_cmd("DELETE",$calendar."/private/full/".$entry->{'IDR'}));
}
#***************************************************************************
# Diese Funktion aendert einen Kalender-Eintrag im Hauptspeicher.
# (Damit diese Aenderung auch im Google-Kalender steht, muss
# der geaenderte Eintrag per update_entry uebergetragen werden.
# Die Uebergabe der zu aendernden Parameter erfolgt per Hash $ch
#
#
# $ch->{'T'} Neuer Titel
# $ch->{'W'} Neuer Ort
# $ch->{'STARTTIME'} Neuer Startzeitpunkt, Format: <jjjj-mm-tt>T<hh:mm:ss>
# $ch->{'ENDTIME'} Neuer Ende-Zeitpunkt, Format: <jjjj-mm-tt>T<hh:mm:ss>
# $ch->{'ABS'} Kommaseparierte neue Teilnehmerliste
# $ch->{'ADD'} Kommaseparierte Liste von hinzuzufuegenden Teilnehmern
# $ch->{'SUBTRACT'} Kommaseparierte Liste von auszuladenden Teilnehmern
#
#
# $ch->{'INVITED'} Kommaseparierte Liste von Teilnehmern, die mit dem
# Vermerk 'invited' versehen werden sollen.
# $ch->{'ACCEPTED'} Kommaseparierte Liste von Teilnehmern, die mit dem
# Vermerk 'accepted' versehen werden sollen.
# $ch->{'TENTATIVE'} Kommaseparierte Liste von Teilnehmern, die mit dem
# Vermerk 'tentative' versehen werden sollen.
# $ch->{'DECLINED'} Kommaseparierte Liste von Teilnehmern, die mit dem
# Vermerk 'declined' versehen werden sollen.
sub change_entry {
my $self = shift;
my $entry = shift;
my $ch = shift; # Aenderungs-Hash
if (!(ref($ch))) {
$ch = {$ch,@_};
}
# return(0) if ($entry->{'ATTENDEE'}->{$entry->{'HOME'}});
my $akt_date = $self->akt_date();
# my $akt_date1 = $akt_date;
# $akt_date1 =~ s/\_//;
my $attendee; my $email; my $o; my $o1; my $text;
my $xml = $entry->{'___'};
delete ($entry->{'NO_NOTIFY'});
if (exists $ch->{'T'}) {
$o = $ch->{'T'};
if ($o =~ s/___NO_NOTIFY___'//gs) {
$entry->{'NO_NOTIFY'};
}
$entry->{'___'} =~ s/(\<title\s.*?\>).*?(<\/title\>)/$1$o$2/s;
$entry->{'___'} =~ s/___NO_NOTIFY___'//gs;
$entry->{'TITLE'} = $o;
}
if (exists $ch->{'W'}) {
$o = $ch->{'W'};
$entry->{'___'} =~ s/(\<gd\:where\s.*?[\'\"]).*?([\'\"])/$1$o$2/s;
$entry->{'WHERE'} = $o;
}
if (exists $ch->{'STARTTIME'}) {
$o = $ch->{'STARTTIME'};
$entry->{'___'} =~ s/(startTime=[\'\"]).*?(\..*?[\'\"])/$1$o$2/s;
$entry->{'STARTTIME'} = $o;
$o =~ /^(.*)T(.*)\:00$/;
$entry->{'STARTDAY'} = $1;
$entry->{'A'} = $2;
}
if (exists $ch->{'ENDTIME'}) {
$o = $ch->{'ENDTIME'};
$entry->{'___'} =~ s/(endTime=[\'\"]).*?(\..*?[\'\"])/$1$o$2/s;
$entry->{'ENDTIME'} = $o;
$o =~ /^(.*)T(.*)\:00$/;
$entry->{'ENDDAY'} = $1;
$entry->{'E'} = $2;
}
# my $termin_date = $entry->{'ENDDAY'} . $entry->{'E'};
# $termin_date =~ s/^20//;
# $termin_date =~ s/[\-\:]//g;
if (exists $ch->{'ABS'}) {
$ch->{'ADD'} = {};
$ch->{'SUBTRACT'} = {%{$entry->{'ATTENDEE'}}};
foreach $o (split(/,/,$ch->{'ABS'})) {
if ($entry->{'ATTENDEE'}->{$o}) {
delete($ch->{'SUBTRACT'}->{$o});
} else {
$ch->{'ADD'}->{$o} = 1;
}
}
$ch->{'ADD'} = join(",",keys %{$ch->{'ADD'}});
$ch->{'SUBTRACT'} = join(",",keys %{$ch->{'SUBTRACT'}});
}
if (exists $ch->{'ADD'}) {
foreach $o (split(/,/,$ch->{'ADD'})) {
($attendee,$email) = $self->att_mail($o);
$o = "";
if (ref($email)) {
$o = $email->[1];
$email = $email->[0];
}
next if ($entry->{'ATTENDEE'}->{$email});
$text = "\n" . <<'TEXT_ENDE' . " \<\/gd\:who\>";
<gd:who rel="http://schemas.google.com/g/2005#event.attendee"
valueString="---ATTENDEE---" email="---EMAIL---">
<gd:attendeeStatus value="http://schemas.google.com/g/2005#event.---INVITED---"/>
TEXT_ENDE
$text =~ s/---ATTENDEE---/$attendee/;
$text =~ s/---EMAIL---/$email/;
if ($o) {
$entry->{'ATTENDEE'}->{$email} = $entry->{'ATTENDEE'}->{$o};
$entry->{'ATTENDEE'}->{$email} =~ /^(.*)([tdaio])/;
$o1 = $2;
if ($o1 eq "d") { $text =~ s/---INVITED---/deleted/; }
elsif ($o1 eq "t") { $text =~ s/---INVITED---/tentative/; }
elsif ($o1 eq "i") { $text =~ s/---INVITED---/invited/; }
elsif ($o1 eq "a") { $text =~ s/---INVITED---/accepted/; }
# if ($termin_date > $akt_date1) {
# $entry->{'ATTENDEE'}->{$email} = $entry->{'ATTENDEE'}->{$email}
# . "," . $akt_date . "d" . "," . $akt_date . "i";
# }
} else {
$text =~ s/---INVITED---/invited/;
$entry->{'ATTENDEE'}->{$email} = $akt_date . "i";
}
$entry->{'___'} =~ s/(.*gd\:when.*?\>)/$1$text/;
}
}
# open(FFILE,">log.txt");
# print FFILE $entry->{'___'} . "\n";
if (exists $ch->{'SUBTRACT'}) {
if ($ch->{'SUBTRACT'} eq "ALL") {
$ch->{'SUBTRACT'} = join(",",keys %{$entry->{'ATTENDEE'}});
}
foreach $o (split(/,/,$ch->{'SUBTRACT'})) {
($attendee,$email) = $self->att_mail($o);
next if (!($entry->{'ATTENDEE'}->{$email}));
$entry->{'___'} =~ s/^(.*)(\<gd\:who)(.*?\s?)(email=[\"\']$email[\"\'].*?\<\/gd\:who\>\s*)/$1/s;
# print FFILE $email . "\n\n" . $entry->{'___'} . "\n";
delete($entry->{'ATTENDEE'}->{$email});
}
}
foreach $text ("accepted","tentative","invited","declined") {
foreach $o (split(/,/,$ch->{uc($text)})) {
($attendee,$email) = $self->att_mail($o);
# print "RR: " . $entry->{'___'} . "\n"; sleep 40;
$entry->{'___'} =~ s/(email\=[\'\"]$email[\'\"].*?event\.)(invited|accepted|declined|tentative|organizer)/$1$text/;
if (!($entry->{'ATTENDEE'}->{$entry->{'HOME'}})) {
my $o1 = substr($text,0,1);
if ($entry->{'ATTENDEE'}->{$email} !~ /$o1$/) {
$entry->{'ATTENDEE'}->{$email} = $entry->{'ATTENDEE'}->{$email} .
"," . $akt_date . $o1;
$entry->{'ATTENDEE'}->{$email} =~ s/^\,//;
}
}
}
}
$o = "";
delete($entry->{'CONTENT'});
if (exists $ch->{'C'}) {
$o = $ch->{'C'};
}
if ($o =~ s/\[(.*?)\]/\[\]/s) {
$entry->{'ATTENDEE'}->{'___INFO___'} = $1;
}
if (%{$entry->{'ATTENDEE'}} and $entry->{'TITLE'} !~ /^ *\./) {
$o = $o . "\n\{" . $self->encode($entry->{'ATTENDEE'});
$o =~ s/\n$//s;
$o = $o . "\}";
}
# print Dumper ($entry) . "\n"; sleep 3;
$o =~ s/^[ \n]*(.*?)[ \n]*$/$1/s;
# if ($entry->{'ATTENDEE'}->{$entry->{'HOME'}}) { # Wenn selbst eingeladen
# $o =~ s/\n\{(.*?)\}//s; # keine Aenderung der Attendee-Listen
# }
if ($entry->{'___'} =~ s/(\<content\s.*?\>).*?(<\/content\>)/$1$o$2/s) {
1;
}
elsif ($entry->{'___'} =~ s/(\<)(content)(\s.*?)(\/)(\>)/$1$2$3$5$o$1$4$2$5/s) {
1;
}
else {
my $o1 = "\<\/title\>\<content type=\'text\'\>" . $o . "\<\/content\>";
$entry->{'___'} =~ s/\<\/title\>/$o1/s;
}
$entry->{'CONTENT'} = $o;
#print "ZZZ: " . $entry->{'___'} . "\n"; sleep 50;
$entry->{'___INTERMEDIATE___'} = $xml;
if ($entry->{'___INTERMEDIATE___'} =~
s/(\<content\s.*?\>).*?(<\/content\>)/$1$o$2/s) {
1;
}
elsif ($entry->{'___INTERMEDIATE___'} =~
s/(\<)(content)(\s.*?)(\/)(\>)/$1$2$3$5$o$1$4$2$5/s) {
1;
}
else {
my $o1 = "\<\/title\>\<content type=\'text\'\>" . $o . "\<\/content\>";
$entry->{'___INTERMEDIATE___'} =~ s/\<\/title\>/$o1/s;
}
if (!($entry->{'NO_NOTIFY'})) {
$o = $xml;
$text = $entry->{'___INTERMEDIATE___'};
# print "WW: $o\n\n$text\n\n"; sleep 3;
$o =~ s/(\<content\s.*?\>)(.*?)\{.*?\}(<\/content\>)/$1$2___CONTENT___$3/s;
$text =~ s/(\<content\s.*?\>)(.*?)\{.*?\}(<\/content\>)/$1$2___CONTENT___$3/s;
if ($o eq $text) {
# print "EQUAL\n"; sleep 6;
$entry->{'NO_NOTIFY'} = 1; # bis auf die Attendee-Liste ist alles gleich
# } else {
# if ($o <= $akt_date) {
# $entry->{'NO_NOTIFY'} = 1;
# } else {
# delete($entry->{'NO_NOTIFY'});
# }
}
}
if ($entry->{'___'} eq $entry->{'___INTERMEDIATE___'}) {
# !(%{$entry->{'ATTENDEE'}})) {
delete ($entry->{'___INTERMEDIATE___'});
}
return(0) if ($xml eq $entry->{'___'}); # wenn nichts geaendert wurde
$entry->{'CHANGED'} = 1;
return($xml); # Wert vorher
}
#***************************************************************************
<<'XXX';
Allgemeine Testfallklasse mit Kalendern <1> bis <n>:
Aktionen:
1. Termin wird eingerichtet (Funktion create_entry) mit#
Kalender <i>, weitere Kalender werden zufaellig mit eingeladen.
1. Termin einrichten in K1
Funktion create_entry. $calendar = K1
XXX
1;