moved deprecated communityhome, dav and yourls to the deprecated-addons repository

This commit is contained in:
Tobias Diekershoff 2018-06-02 11:23:11 +02:00
commit 31520f804d
675 changed files with 195144 additions and 0 deletions

17
communityhome/README.md Normal file
View file

@ -0,0 +1,17 @@
Community Home
--------------
This addon overwrites the default home page shown to anonymous users.
On the sidebar there are the login form, last ten users (if they chose
to be in the site directory), last ten public photos and last ten
"likes" sent by a site user or about a site user's item.
In the main content is shown the community stream. This addon doesn't
honor your community page visibility site setting: the community
stream is shown also if you have choose to not show the community page.
If 'home.html' is found in your friendica root, its content is inserted
before community stream
By default no features are enabled, you can edit this addon's settings
through the admin panel.

View file

@ -0,0 +1,48 @@
aside form { position: relative }
aside #login_standard {
width: 200px;
position: absolute;
float:none;
height: 100px;
display: block;
}
aside #login_openid {
width: 200px;
position: absolute;
float:none;
margin-left: 0px;
height: 100px;
display: none;
}
aside #label-login-name,
aside #login-name,
aside #label-login-password,
aside #login-password {
float: none !important;
}
aside #login-name-end,
aside #login-password-end,
aside #login-extra-end,
aside #login-submit-end,
aside #login-extra-filler {
float: none; height: 5px;
margin: 0px;
}
aside #login-submit-button { margin-left: 100px; }
aside .items-wrapper,
aside #login-extra-links { overflow: auto; width: 100%;}
aside .directory-item { width: 55px; height: 55px; vertical-align: center; text-align: center; }
aside .directory-photo { margin: 0px; }
aside .directory-photo-img { max-width: 48px; max-height: 48px; }
aside #likes { margin: 0px; padding: 0px; list-style: none; }
aside #div_id_remember { overflow: auto; width: 100%; padding-top:120px;}
#login_openid input { width: 160px; }
/* frio fix */
body.mod-home .navbar.navbar-fixed-top ul.nav.navbar-nav #nav-login {
display: block;
}

View file

@ -0,0 +1,225 @@
<?php
/**
* Name: Community home
* Description: Show last community activity in homepage
* Version: 2.0
* Author: Fabio Comuni <http://kirgroup.com/profile/fabrixxm>
* Status: Unsupported
*/
use Friendica\App;
use Friendica\Core\Addon;
use Friendica\Core\Config;
use Friendica\Core\L10n;
use Friendica\Module\Login;
require_once 'mod/community.php';
function communityhome_install()
{
Addon::registerHook('home_content', 'addon/communityhome/communityhome.php', 'communityhome_home');
logger("installed communityhome");
}
function communityhome_uninstall()
{
Addon::unregisterHook('home_content', 'addon/communityhome/communityhome.php', 'communityhome_home');
logger("removed communityhome");
}
function communityhome_getopts()
{
return [
'hidelogin' => L10n::t('Hide login form'),
'showlastusers' => L10n::t('Show last new users'),
'showlastphotos' => L10n::t('Show last photos'),
'showlastlike' => L10n::t('Show last liked items'),
'showcommunitystream' => L10n::t('Show community stream')
];
}
function communityhome_addon_admin(App $a, &$o)
{
$tpl = get_markup_template('settings.tpl', 'addon/communityhome/');
$opts = communityhome_getopts();
$ctx = [
'$submit' => L10n::t("Submit"),
'$fields' => [],
];
foreach ($opts as $k => $v) {
$ctx['fields'][] = ['communityhome_' . $k, $v, Config::get('communityhome', $k)];
}
$o = replace_macros($tpl, $ctx);
}
function communityhome_addon_admin_post(App $a)
{
if (x($_POST, 'communityhome-submit')) {
$opts = communityhome_getopts();
foreach ($opts as $k => $v) {
Config::set('communityhome', $k, x($_POST, 'communityhome_' . $k));
}
}
}
function communityhome_home(App $a, &$o)
{
// custom css
$a->page['htmlhead'] .= '<link rel="stylesheet" type="text/css" href="' . $a->get_baseurl() . '/addon/communityhome/communityhome.css" media="all" />';
if (!Config::get('communityhome', 'hidelogin')) {
$aside = [
'$tab_1' => L10n::t('Login'),
'$tab_2' => L10n::t('OpenID'),
'$noOid' => Config::get('system', 'no_openid'),
];
// login form
$aside['$login_title'] = L10n::t('Login');
$aside['$login_form'] = Login::form($a->query_string, $a->config['register_policy'] == REGISTER_CLOSED ? false : true);
} else {
$aside = [
//'$tab_1' => L10n::t('Login'),
//'$tab_2' => L10n::t('OpenID'),
//'$noOid' => Config::get('system','no_openid'),
];
}
// last 12 users
if (Config::get('communityhome', 'showlastusers')) {
$aside['$lastusers_title'] = L10n::t('Latest users');
$aside['$lastusers_items'] = [];
$sql_extra = "";
$publish = (Config::get('system', 'publish_all') ? '' : " AND `publish` = 1 " );
$order = " ORDER BY `register_date` DESC ";
$r = q("SELECT `profile`.*, `profile`.`uid` AS `profile_uid`, `user`.`nickname`
FROM `profile` LEFT JOIN `user` ON `user`.`uid` = `profile`.`uid`
WHERE `is-default` = 1 $publish AND `user`.`blocked` = 0 $sql_extra $order LIMIT %d, %d ",
0,
12
);
# $tpl = file_get_contents( dirname(__file__).'/directory_item.tpl');
$tpl = get_markup_template('directory_item.tpl', 'addon/communityhome/');
if (count($r)) {
$photo = 'thumb';
foreach ($r as $rr) {
$profile_link = $a->get_baseurl() . '/profile/' . ((strlen($rr['nickname'])) ? $rr['nickname'] : $rr['profile_uid']);
$entry = replace_macros($tpl, [
'$id' => $rr['id'],
'$profile_link' => $profile_link,
'$photo' => $rr[$photo],
'$alt_text' => $rr['name'],
]);
$aside['$lastusers_items'][] = $entry;
}
}
}
// last 12 photos
if (Config::get('communityhome', 'showlastphotos')) {
$aside['$photos_title'] = L10n::t('Latest photos');
$aside['$photos_items'] = [];
$r = q("SELECT `photo`.`id`, `photo`.`resource-id`, `photo`.`scale`, `photo`.`desc`, `user`.`nickname`, `user`.`username` FROM
(SELECT `resource-id`, MAX(`scale`) as maxscale FROM `photo`
WHERE `profile`=0 AND `contact-id`=0 AND `album` NOT IN ('Contact Photos', '%s', 'Profile Photos', '%s')
AND `allow_cid`='' AND `allow_gid`='' AND `deny_cid`='' AND `deny_gid`='' GROUP BY `resource-id`) AS `t1`
INNER JOIN `photo` ON `photo`.`resource-id`=`t1`.`resource-id` AND `photo`.`scale` = `t1`.`maxscale`,
`user`
WHERE `user`.`uid` = `photo`.`uid`
AND `user`.`blockwall`=0
AND `user`.`hidewall` = 0
ORDER BY `photo`.`edited` DESC
LIMIT 0, 12",
dbesc(L10n::t('Contact Photos')),
dbesc(L10n::t('Profile Photos'))
);
if (count($r)) {
# $tpl = file_get_contents( dirname(__file__).'/directory_item.tpl');
$tpl = get_markup_template('directory_item.tpl', 'addon/communityhome/');
foreach ($r as $rr) {
$photo_page = $a->get_baseurl() . '/photos/' . $rr['nickname'] . '/image/' . $rr['resource-id'];
$photo_url = $a->get_baseurl() . '/photo/' . $rr['resource-id'] . '-' . $rr['scale'] . '.jpg';
$entry = replace_macros($tpl, [
'$id' => $rr['id'],
'$profile_link' => $photo_page,
'$photo' => $photo_url,
'$photo_user' => $rr['username'],
'$photo_title' => $rr['desc']
]);
$aside['$photos_items'][] = $entry;
}
}
}
// last 10 liked items
if (Config::get('communityhome', 'showlastlike')) {
$aside['$like_title'] = L10n::t('Latest likes');
$aside['$like_items'] = [];
$r = q("SELECT `T1`.`created`, `T1`.`liker`, `T1`.`liker-link`, `item`.* FROM
(SELECT `parent-uri`, `created`, `author-name` AS `liker`,`author-link` AS `liker-link`
FROM `item` WHERE `verb`='http://activitystrea.ms/schema/1.0/like' GROUP BY `parent-uri` ORDER BY `created` DESC) AS T1
INNER JOIN `item` ON `item`.`uri`=`T1`.`parent-uri`
WHERE `T1`.`liker-link` LIKE '%s%%' OR `item`.`author-link` LIKE '%s%%'
GROUP BY `uri`
ORDER BY `T1`.`created` DESC
LIMIT 0,10",
$a->get_baseurl(),
$a->get_baseurl()
);
foreach ($r as $rr) {
$author = '<a href="' . $rr['liker-link'] . '">' . $rr['liker'] . '</a>';
$objauthor = '<a href="' . $rr['author-link'] . '">' . $rr['author-name'] . '</a>';
//var_dump($rr['verb'],$rr['object-type']); killme();
switch ($rr['verb']) {
case 'http://activitystrea.ms/schema/1.0/post':
switch ($rr['object-type']) {
case 'http://activitystrea.ms/schema/1.0/event':
$post_type = L10n::t('event');
break;
default:
$post_type = L10n::t('status');
}
break;
default:
if ($rr['resource-id']) {
$post_type = L10n::t('photo');
$m = [];
preg_match("/\[url=([^]]*)\]/", $rr['body'], $m);
$rr['plink'] = $m[1];
} else {
$post_type = L10n::t('status');
}
}
$plink = '<a href="' . $rr['plink'] . '">' . $post_type . '</a>';
$aside['$like_items'][] = L10n::t('%1$s likes %2$s\'s %3$s', $author, $objauthor, $plink);
}
}
# $tpl = file_get_contents(dirname(__file__).'/communityhome.tpl');
$tpl = get_markup_template('communityhome.tpl', 'addon/communityhome/');
$a->page['aside'] = replace_macros($tpl, $aside);
$o = '<h1>' . ((x($a->config, 'sitename')) ? L10n::t("Welcome to %s", $a->config['sitename']) : "" ) . '</h1>';
if (file_exists('home.html')) $o = file_get_contents('home.html');
if (Config::get('communityhome', 'showcommunitystream')) {
$oldset = Config::get('system', 'community_page_style');
if ($oldset == CP_NO_COMMUNITY_PAGE) Config::set('system', 'community_page_style', CP_USERS_ON_SERVER);
$o .= community_content($a, 1);
if ($oldset == CP_NO_COMMUNITY_PAGE) Config::set('system', 'community_page_style', $oldset);
}
}

View file

@ -0,0 +1,72 @@
# ADDON communityhome
# Copyright (C)
# This file is distributed under the same license as the Friendica communityhome addon package.
#
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-27 05:01-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"Language: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: communityhome.php:28 communityhome.php:34
msgid "Login"
msgstr ""
#: communityhome.php:29
msgid "OpenID"
msgstr ""
#: communityhome.php:39
msgid "Latest users"
msgstr ""
#: communityhome.php:84
msgid "Most active users"
msgstr ""
#: communityhome.php:102
msgid "Latest photos"
msgstr ""
#: communityhome.php:115
msgid "Contact Photos"
msgstr ""
#: communityhome.php:116
msgid "Profile Photos"
msgstr ""
#: communityhome.php:141
msgid "Latest likes"
msgstr ""
#: communityhome.php:163
msgid "event"
msgstr ""
#: communityhome.php:166 communityhome.php:175
msgid "status"
msgstr ""
#: communityhome.php:171
msgid "photo"
msgstr ""
#: communityhome.php:180
#, php-format
msgid "%1$s likes %2$s's %3$s"
msgstr ""
#: communityhome.php:189
#, php-format
msgid "Welcome to %s"
msgstr ""

View file

@ -0,0 +1,14 @@
<?php
$a->strings["Login"] = "Identifica't";
$a->strings["OpenID"] = "OpenID";
$a->strings["Latest users"] = "Últims usuaris";
$a->strings["Most active users"] = "Usuaris més actius";
$a->strings["Latest photos"] = "Darreres fotos";
$a->strings["Contact Photos"] = "Fotos de Contacte";
$a->strings["Profile Photos"] = "Fotos del Perfil";
$a->strings["Latest likes"] = "Darrers agrada";
$a->strings["event"] = "esdeveniment";
$a->strings["status"] = "estatus";
$a->strings["photo"] = "foto";
$a->strings["Welcome to %s"] = "Benvingut a %s";

View file

@ -0,0 +1,74 @@
# ADDON communityhome
# Copyright (C)
# This file is distributed under the same license as the Friendica communityhome addon package.
#
#
# Translators:
# Michal Šupler <msupler@gmail.com>, 2014
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-27 05:01-0500\n"
"PO-Revision-Date: 2014-07-07 18:33+0000\n"
"Last-Translator: Michal Šupler <msupler@gmail.com>\n"
"Language-Team: Czech (http://www.transifex.com/projects/p/friendica/language/cs/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: cs\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
#: communityhome.php:28 communityhome.php:34
msgid "Login"
msgstr "Přihlásit se"
#: communityhome.php:29
msgid "OpenID"
msgstr "OpenID"
#: communityhome.php:39
msgid "Latest users"
msgstr "Poslední uživatelé"
#: communityhome.php:84
msgid "Most active users"
msgstr "Nejaktivnější uživatelé"
#: communityhome.php:102
msgid "Latest photos"
msgstr "Poslední fotky"
#: communityhome.php:115
msgid "Contact Photos"
msgstr "Fotogalerie kontaktu"
#: communityhome.php:116
msgid "Profile Photos"
msgstr "Profilové fotografie"
#: communityhome.php:141
msgid "Latest likes"
msgstr "Poslední \"líbí se mi\""
#: communityhome.php:163
msgid "event"
msgstr "událost"
#: communityhome.php:166 communityhome.php:175
msgid "status"
msgstr "Stav"
#: communityhome.php:171
msgid "photo"
msgstr "fotografie"
#: communityhome.php:180
#, php-format
msgid "%1$s likes %2$s's %3$s"
msgstr "Uživateli %1$s se líbí %3$s uživatele %2$s"
#: communityhome.php:189
#, php-format
msgid "Welcome to %s"
msgstr "Vítá Vás %s"

View file

@ -0,0 +1,20 @@
<?php
if(! function_exists("string_plural_select_cs")) {
function string_plural_select_cs($n){
return ($n==1) ? 0 : ($n>=2 && $n<=4) ? 1 : 2;;
}}
;
$a->strings["Login"] = "Přihlásit se";
$a->strings["OpenID"] = "OpenID";
$a->strings["Latest users"] = "Poslední uživatelé";
$a->strings["Most active users"] = "Nejaktivnější uživatelé";
$a->strings["Latest photos"] = "Poslední fotky";
$a->strings["Contact Photos"] = "Fotogalerie kontaktu";
$a->strings["Profile Photos"] = "Profilové fotografie";
$a->strings["Latest likes"] = "Poslední \"líbí se mi\"";
$a->strings["event"] = "událost";
$a->strings["status"] = "Stav";
$a->strings["photo"] = "fotografie";
$a->strings["%1\$s likes %2\$s's %3\$s"] = "Uživateli %1\$s se líbí %3\$s uživatele %2\$s";
$a->strings["Welcome to %s"] = "Vítá Vás %s";

View file

@ -0,0 +1,74 @@
# ADDON communityhome
# Copyright (C)
# This file is distributed under the same license as the Friendica communityhome addon package.
#
#
# Translators:
# bavatar <tobias.diekershoff@gmx.net>, 2014
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-27 05:01-0500\n"
"PO-Revision-Date: 2014-07-08 19:06+0000\n"
"Last-Translator: bavatar <tobias.diekershoff@gmx.net>\n"
"Language-Team: German (http://www.transifex.com/projects/p/friendica/language/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: communityhome.php:28 communityhome.php:34
msgid "Login"
msgstr "Anmeldung"
#: communityhome.php:29
msgid "OpenID"
msgstr "OpenID"
#: communityhome.php:39
msgid "Latest users"
msgstr "Letzte Benutzer"
#: communityhome.php:84
msgid "Most active users"
msgstr "Aktivste Nutzer"
#: communityhome.php:102
msgid "Latest photos"
msgstr "Neueste Fotos"
#: communityhome.php:115
msgid "Contact Photos"
msgstr "Kontaktbilder"
#: communityhome.php:116
msgid "Profile Photos"
msgstr "Profilbilder"
#: communityhome.php:141
msgid "Latest likes"
msgstr "Neueste Favoriten"
#: communityhome.php:163
msgid "event"
msgstr "Veranstaltung"
#: communityhome.php:166 communityhome.php:175
msgid "status"
msgstr "Status"
#: communityhome.php:171
msgid "photo"
msgstr "Foto"
#: communityhome.php:180
#, php-format
msgid "%1$s likes %2$s's %3$s"
msgstr "%1$s mag %2$s's %3$s"
#: communityhome.php:189
#, php-format
msgid "Welcome to %s"
msgstr "Willkommen zu %s"

View file

@ -0,0 +1,20 @@
<?php
if(! function_exists("string_plural_select_de")) {
function string_plural_select_de($n){
return ($n != 1);;
}}
;
$a->strings["Login"] = "Anmeldung";
$a->strings["OpenID"] = "OpenID";
$a->strings["Latest users"] = "Letzte Benutzer";
$a->strings["Most active users"] = "Aktivste Nutzer";
$a->strings["Latest photos"] = "Neueste Fotos";
$a->strings["Contact Photos"] = "Kontaktbilder";
$a->strings["Profile Photos"] = "Profilbilder";
$a->strings["Latest likes"] = "Neueste Favoriten";
$a->strings["event"] = "Veranstaltung";
$a->strings["status"] = "Status";
$a->strings["photo"] = "Foto";
$a->strings["%1\$s likes %2\$s's %3\$s"] = "%1\$s mag %2\$s's %3\$s";
$a->strings["Welcome to %s"] = "Willkommen zu %s";

View file

@ -0,0 +1,14 @@
<?php
$a->strings["Login"] = "Ensaluti";
$a->strings["OpenID"] = "OpenID";
$a->strings["Latest users"] = "Ĵusaj uzantoj";
$a->strings["Most active users"] = "Plej aktivaj uzantoj";
$a->strings["Latest photos"] = "Ĵusaj bildoj";
$a->strings["Contact Photos"] = "Kontaktbildoj";
$a->strings["Profile Photos"] = "Profilbildoj";
$a->strings["Latest likes"] = "Ĵusaj ŝatitaĵoj";
$a->strings["event"] = "okazo";
$a->strings["status"] = "staton";
$a->strings["photo"] = "bildo";
$a->strings["Welcome to %s"] = "Bonvenon ĉe %s";

View file

@ -0,0 +1,73 @@
# ADDON communityhome
# Copyright (C)
# This file is distributed under the same license as the Friendica communityhome addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-27 05:01-0500\n"
"PO-Revision-Date: 2016-10-10 20:53+0000\n"
"Last-Translator: Athalbert\n"
"Language-Team: Spanish (http://www.transifex.com/Friendica/friendica/language/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: communityhome.php:28 communityhome.php:34
msgid "Login"
msgstr "Acceder"
#: communityhome.php:29
msgid "OpenID"
msgstr "ID Abierta"
#: communityhome.php:39
msgid "Latest users"
msgstr "Usuarios recientes"
#: communityhome.php:84
msgid "Most active users"
msgstr "Usuarios más activos"
#: communityhome.php:102
msgid "Latest photos"
msgstr "Fotos recientes"
#: communityhome.php:115
msgid "Contact Photos"
msgstr "Fotos de contacto"
#: communityhome.php:116
msgid "Profile Photos"
msgstr "Fotos de perfil"
#: communityhome.php:141
msgid "Latest likes"
msgstr "Últomos Me gusta"
#: communityhome.php:163
msgid "event"
msgstr "evento"
#: communityhome.php:166 communityhome.php:175
msgid "status"
msgstr "estatus social"
#: communityhome.php:171
msgid "photo"
msgstr "foto"
#: communityhome.php:180
#, php-format
msgid "%1$s likes %2$s's %3$s"
msgstr "A %1$s le gusta %2$s's %3$s"
#: communityhome.php:189
#, php-format
msgid "Welcome to %s"
msgstr "Bienvenido a %s"

View file

@ -0,0 +1,20 @@
<?php
if(! function_exists("string_plural_select_es")) {
function string_plural_select_es($n){
return ($n != 1);;
}}
;
$a->strings["Login"] = "Acceder";
$a->strings["OpenID"] = "ID Abierta";
$a->strings["Latest users"] = "Usuarios recientes";
$a->strings["Most active users"] = "Usuarios más activos";
$a->strings["Latest photos"] = "Fotos recientes";
$a->strings["Contact Photos"] = "Fotos de contacto";
$a->strings["Profile Photos"] = "Fotos de perfil";
$a->strings["Latest likes"] = "Últomos Me gusta";
$a->strings["event"] = "evento";
$a->strings["status"] = "estatus social";
$a->strings["photo"] = "foto";
$a->strings["%1\$s likes %2\$s's %3\$s"] = "A %1\$s le gusta %2\$s's %3\$s";
$a->strings["Welcome to %s"] = "Bienvenido a %s";

View file

@ -0,0 +1,75 @@
# ADDON communityhome
# Copyright (C)
# This file is distributed under the same license as the Friendica communityhome addon package.
#
#
# Translators:
# Kris, 2018
# Kris, 2018
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-27 05:01-0500\n"
"PO-Revision-Date: 2018-04-18 14:52+0000\n"
"Last-Translator: Kris\n"
"Language-Team: Finnish (Finland) (http://www.transifex.com/Friendica/friendica/language/fi_FI/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: fi_FI\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: communityhome.php:28 communityhome.php:34
msgid "Login"
msgstr "Kirjaudu"
#: communityhome.php:29
msgid "OpenID"
msgstr "OpenID"
#: communityhome.php:39
msgid "Latest users"
msgstr "Viimeisimmät käyttäjät"
#: communityhome.php:84
msgid "Most active users"
msgstr "Aktiivisimmat käyttäjät"
#: communityhome.php:102
msgid "Latest photos"
msgstr "Viimeisimmät kuvat"
#: communityhome.php:115
msgid "Contact Photos"
msgstr "Kontaktikuvat"
#: communityhome.php:116
msgid "Profile Photos"
msgstr "Profiilikuvat"
#: communityhome.php:141
msgid "Latest likes"
msgstr "Viimeisimmät tykkäykset"
#: communityhome.php:163
msgid "event"
msgstr "tapahtuma"
#: communityhome.php:166 communityhome.php:175
msgid "status"
msgstr "tila"
#: communityhome.php:171
msgid "photo"
msgstr "kuva"
#: communityhome.php:180
#, php-format
msgid "%1$s likes %2$s's %3$s"
msgstr ""
#: communityhome.php:189
#, php-format
msgid "Welcome to %s"
msgstr "Tervetuloa %s"

View file

@ -0,0 +1,20 @@
<?php
if(! function_exists("string_plural_select_fi_fi")) {
function string_plural_select_fi_fi($n){
return ($n != 1);;
}}
;
$a->strings["Login"] = "Kirjaudu";
$a->strings["OpenID"] = "OpenID";
$a->strings["Latest users"] = "Viimeisimmät käyttäjät";
$a->strings["Most active users"] = "Aktiivisimmat käyttäjät";
$a->strings["Latest photos"] = "Viimeisimmät kuvat";
$a->strings["Contact Photos"] = "Kontaktikuvat";
$a->strings["Profile Photos"] = "Profiilikuvat";
$a->strings["Latest likes"] = "Viimeisimmät tykkäykset";
$a->strings["event"] = "tapahtuma";
$a->strings["status"] = "tila";
$a->strings["photo"] = "kuva";
$a->strings["%1\$s likes %2\$s's %3\$s"] = "";
$a->strings["Welcome to %s"] = "Tervetuloa %s";

View file

@ -0,0 +1,75 @@
# ADDON communityhome
# Copyright (C)
# This file is distributed under the same license as the Friendica communityhome addon package.
#
#
# Translators:
# Hypolite Petovan <mrpetovan@gmail.com>, 2016
# StefOfficiel <pichard.stephane@free.fr>, 2015
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-27 05:01-0500\n"
"PO-Revision-Date: 2016-09-24 03:05+0000\n"
"Last-Translator: Hypolite Petovan <mrpetovan@gmail.com>\n"
"Language-Team: French (http://www.transifex.com/Friendica/friendica/language/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: fr\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: communityhome.php:28 communityhome.php:34
msgid "Login"
msgstr "Identifiant"
#: communityhome.php:29
msgid "OpenID"
msgstr "OpenID"
#: communityhome.php:39
msgid "Latest users"
msgstr "Derniers utilisateurs"
#: communityhome.php:84
msgid "Most active users"
msgstr "Utilisateurs les plus actifs"
#: communityhome.php:102
msgid "Latest photos"
msgstr "Dernières photos"
#: communityhome.php:115
msgid "Contact Photos"
msgstr "Photos du contact"
#: communityhome.php:116
msgid "Profile Photos"
msgstr "Photos de profil"
#: communityhome.php:141
msgid "Latest likes"
msgstr "Derniers likes"
#: communityhome.php:163
msgid "event"
msgstr "événement"
#: communityhome.php:166 communityhome.php:175
msgid "status"
msgstr "statut"
#: communityhome.php:171
msgid "photo"
msgstr "photo"
#: communityhome.php:180
#, php-format
msgid "%1$s likes %2$s's %3$s"
msgstr "%1$s aime %3$s de %2$s"
#: communityhome.php:189
#, php-format
msgid "Welcome to %s"
msgstr "Bienvenue sur %s"

View file

@ -0,0 +1,20 @@
<?php
if(! function_exists("string_plural_select_fr")) {
function string_plural_select_fr($n){
return ($n > 1);;
}}
;
$a->strings["Login"] = "Identifiant";
$a->strings["OpenID"] = "OpenID";
$a->strings["Latest users"] = "Derniers utilisateurs";
$a->strings["Most active users"] = "Utilisateurs les plus actifs";
$a->strings["Latest photos"] = "Dernières photos";
$a->strings["Contact Photos"] = "Photos du contact";
$a->strings["Profile Photos"] = "Photos de profil";
$a->strings["Latest likes"] = "Derniers likes";
$a->strings["event"] = "événement";
$a->strings["status"] = "statut";
$a->strings["photo"] = "photo";
$a->strings["%1\$s likes %2\$s's %3\$s"] = "%1\$s aime %3\$s de %2\$s";
$a->strings["Welcome to %s"] = "Bienvenue sur %s";

View file

@ -0,0 +1,74 @@
# ADDON communityhome
# Copyright (C)
# This file is distributed under the same license as the Friendica communityhome addon package.
#
#
# Translators:
# Sveinn í Felli <sv1@fellsnet.is>, 2018
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-27 05:01-0500\n"
"PO-Revision-Date: 2018-05-24 15:16+0000\n"
"Last-Translator: Sveinn í Felli <sv1@fellsnet.is>\n"
"Language-Team: Icelandic (http://www.transifex.com/Friendica/friendica/language/is/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: is\n"
"Plural-Forms: nplurals=2; plural=(n % 10 != 1 || n % 100 == 11);\n"
#: communityhome.php:28 communityhome.php:34
msgid "Login"
msgstr "Innskráning"
#: communityhome.php:29
msgid "OpenID"
msgstr ""
#: communityhome.php:39
msgid "Latest users"
msgstr ""
#: communityhome.php:84
msgid "Most active users"
msgstr ""
#: communityhome.php:102
msgid "Latest photos"
msgstr ""
#: communityhome.php:115
msgid "Contact Photos"
msgstr ""
#: communityhome.php:116
msgid "Profile Photos"
msgstr ""
#: communityhome.php:141
msgid "Latest likes"
msgstr ""
#: communityhome.php:163
msgid "event"
msgstr ""
#: communityhome.php:166 communityhome.php:175
msgid "status"
msgstr ""
#: communityhome.php:171
msgid "photo"
msgstr ""
#: communityhome.php:180
#, php-format
msgid "%1$s likes %2$s's %3$s"
msgstr ""
#: communityhome.php:189
#, php-format
msgid "Welcome to %s"
msgstr ""

View file

@ -0,0 +1,21 @@
<?php
if(! function_exists("string_plural_select_is")) {
function string_plural_select_is($n){
$n = intval($n);
return ($n % 10 != 1 || $n % 100 == 11);;
}}
;
$a->strings["Login"] = "Innskráning";
$a->strings["OpenID"] = "";
$a->strings["Latest users"] = "";
$a->strings["Most active users"] = "";
$a->strings["Latest photos"] = "";
$a->strings["Contact Photos"] = "";
$a->strings["Profile Photos"] = "";
$a->strings["Latest likes"] = "";
$a->strings["event"] = "";
$a->strings["status"] = "";
$a->strings["photo"] = "";
$a->strings["%1\$s likes %2\$s's %3\$s"] = "";
$a->strings["Welcome to %s"] = "";

View file

@ -0,0 +1,74 @@
# ADDON communityhome
# Copyright (C)
# This file is distributed under the same license as the Friendica communityhome addon package.
#
#
# Translators:
# fabrixxm <fabrix.xm@gmail.com>, 2014
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-27 05:01-0500\n"
"PO-Revision-Date: 2017-09-20 06:07+0000\n"
"Last-Translator: fabrixxm <fabrix.xm@gmail.com>\n"
"Language-Team: Italian (http://www.transifex.com/Friendica/friendica/language/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: it\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: communityhome.php:28 communityhome.php:34
msgid "Login"
msgstr "Accedi"
#: communityhome.php:29
msgid "OpenID"
msgstr "OpenID"
#: communityhome.php:39
msgid "Latest users"
msgstr "Ultimi utenti"
#: communityhome.php:84
msgid "Most active users"
msgstr "Utenti più attivi"
#: communityhome.php:102
msgid "Latest photos"
msgstr "Ultime foto"
#: communityhome.php:115
msgid "Contact Photos"
msgstr "Foto dei contatti"
#: communityhome.php:116
msgid "Profile Photos"
msgstr "Foto del profilo"
#: communityhome.php:141
msgid "Latest likes"
msgstr "Ultimi \"mi piace\""
#: communityhome.php:163
msgid "event"
msgstr "l'evento"
#: communityhome.php:166 communityhome.php:175
msgid "status"
msgstr "lo stato"
#: communityhome.php:171
msgid "photo"
msgstr "la foto"
#: communityhome.php:180
#, php-format
msgid "%1$s likes %2$s's %3$s"
msgstr "a %1$s piace %2$s di %3$s"
#: communityhome.php:189
#, php-format
msgid "Welcome to %s"
msgstr "Benvenuto su %s"

View file

@ -0,0 +1,20 @@
<?php
if(! function_exists("string_plural_select_it")) {
function string_plural_select_it($n){
return ($n != 1);;
}}
;
$a->strings["Login"] = "Accedi";
$a->strings["OpenID"] = "OpenID";
$a->strings["Latest users"] = "Ultimi utenti";
$a->strings["Most active users"] = "Utenti più attivi";
$a->strings["Latest photos"] = "Ultime foto";
$a->strings["Contact Photos"] = "Foto dei contatti";
$a->strings["Profile Photos"] = "Foto del profilo";
$a->strings["Latest likes"] = "Ultimi \"mi piace\"";
$a->strings["event"] = "l'evento";
$a->strings["status"] = "lo stato";
$a->strings["photo"] = "la foto";
$a->strings["%1\$s likes %2\$s's %3\$s"] = "a %1\$s piace %2\$s di %3\$s";
$a->strings["Welcome to %s"] = "Benvenuto su %s";

View file

@ -0,0 +1,14 @@
<?php
$a->strings["Login"] = "Logg inn";
$a->strings["OpenID"] = "";
$a->strings["Latest users"] = "";
$a->strings["Most active users"] = "";
$a->strings["Latest photos"] = "";
$a->strings["Contact Photos"] = "Kontaktbilder";
$a->strings["Profile Photos"] = "Profilbilder";
$a->strings["Latest likes"] = "";
$a->strings["event"] = "hendelse";
$a->strings["status"] = "status";
$a->strings["photo"] = "bilde";
$a->strings["Welcome to %s"] = "Velkommen til %s";

View file

@ -0,0 +1,74 @@
# ADDON communityhome
# Copyright (C)
# This file is distributed under the same license as the Friendica communityhome addon package.
#
#
# Translators:
# Waldemar Stoczkowski <waldemar.stoczkowski@gmail.com>, 2018
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-27 05:01-0500\n"
"PO-Revision-Date: 2018-04-18 20:16+0000\n"
"Last-Translator: Waldemar Stoczkowski <waldemar.stoczkowski@gmail.com>\n"
"Language-Team: Polish (http://www.transifex.com/Friendica/friendica/language/pl/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pl\n"
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
#: communityhome.php:28 communityhome.php:34
msgid "Login"
msgstr "Zaloguj się"
#: communityhome.php:29
msgid "OpenID"
msgstr "OpenID"
#: communityhome.php:39
msgid "Latest users"
msgstr "Ostatni użytkownicy"
#: communityhome.php:84
msgid "Most active users"
msgstr "Najbardziej aktywni użytkownicy"
#: communityhome.php:102
msgid "Latest photos"
msgstr "Najnowsze Zdjęcia"
#: communityhome.php:115
msgid "Contact Photos"
msgstr "Zdjęcia kontaktu"
#: communityhome.php:116
msgid "Profile Photos"
msgstr "Zdjęcie profilowe"
#: communityhome.php:141
msgid "Latest likes"
msgstr "Najnowsze polubienia"
#: communityhome.php:163
msgid "event"
msgstr "zdarzenie"
#: communityhome.php:166 communityhome.php:175
msgid "status"
msgstr "status"
#: communityhome.php:171
msgid "photo"
msgstr "zdjęcie"
#: communityhome.php:180
#, php-format
msgid "%1$s likes %2$s's %3$s"
msgstr "%1$slubi %2$s %3$s "
#: communityhome.php:189
#, php-format
msgid "Welcome to %s"
msgstr "Witamy w %s"

View file

@ -0,0 +1,20 @@
<?php
if(! function_exists("string_plural_select_pl")) {
function string_plural_select_pl($n){
return ($n==1 ? 0 : ($n%10>=2 && $n%10<=4) && ($n%100<12 || $n%100>14) ? 1 : $n!=1 && ($n%10>=0 && $n%10<=1) || ($n%10>=5 && $n%10<=9) || ($n%100>=12 && $n%100<=14) ? 2 : 3);;
}}
;
$a->strings["Login"] = "Zaloguj się";
$a->strings["OpenID"] = "OpenID";
$a->strings["Latest users"] = "Ostatni użytkownicy";
$a->strings["Most active users"] = "Najbardziej aktywni użytkownicy";
$a->strings["Latest photos"] = "Najnowsze Zdjęcia";
$a->strings["Contact Photos"] = "Zdjęcia kontaktu";
$a->strings["Profile Photos"] = "Zdjęcie profilowe";
$a->strings["Latest likes"] = "Najnowsze polubienia";
$a->strings["event"] = "zdarzenie";
$a->strings["status"] = "status";
$a->strings["photo"] = "zdjęcie";
$a->strings["%1\$s likes %2\$s's %3\$s"] = "%1\$slubi %2\$s %3\$s ";
$a->strings["Welcome to %s"] = "Witamy w %s";

View file

@ -0,0 +1,74 @@
# ADDON communityhome
# Copyright (C)
# This file is distributed under the same license as the Friendica communityhome addon package.
#
#
# Translators:
# John Brazil, 2015
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-27 05:01-0500\n"
"PO-Revision-Date: 2015-01-31 01:36+0000\n"
"Last-Translator: John Brazil\n"
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/friendica/language/pt_BR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: pt_BR\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
#: communityhome.php:28 communityhome.php:34
msgid "Login"
msgstr "Entrar"
#: communityhome.php:29
msgid "OpenID"
msgstr "OpenID"
#: communityhome.php:39
msgid "Latest users"
msgstr "Usuários mais recentes"
#: communityhome.php:84
msgid "Most active users"
msgstr "Usuários mais ativos"
#: communityhome.php:102
msgid "Latest photos"
msgstr "Fotos mais recentes"
#: communityhome.php:115
msgid "Contact Photos"
msgstr "Fotos dos Contatos"
#: communityhome.php:116
msgid "Profile Photos"
msgstr "Fotos do Perfil"
#: communityhome.php:141
msgid "Latest likes"
msgstr "Curtidas recentes"
#: communityhome.php:163
msgid "event"
msgstr "evento"
#: communityhome.php:166 communityhome.php:175
msgid "status"
msgstr "status"
#: communityhome.php:171
msgid "photo"
msgstr "foto"
#: communityhome.php:180
#, php-format
msgid "%1$s likes %2$s's %3$s"
msgstr "%1$s curtiu %2$s que publicou %3$s"
#: communityhome.php:189
#, php-format
msgid "Welcome to %s"
msgstr "Bem-vindo a %s"

View file

@ -0,0 +1,20 @@
<?php
if(! function_exists("string_plural_select_pt_br")) {
function string_plural_select_pt_br($n){
return ($n > 1);;
}}
;
$a->strings["Login"] = "Entrar";
$a->strings["OpenID"] = "OpenID";
$a->strings["Latest users"] = "Usuários mais recentes";
$a->strings["Most active users"] = "Usuários mais ativos";
$a->strings["Latest photos"] = "Fotos mais recentes";
$a->strings["Contact Photos"] = "Fotos dos Contatos";
$a->strings["Profile Photos"] = "Fotos do Perfil";
$a->strings["Latest likes"] = "Curtidas recentes";
$a->strings["event"] = "evento";
$a->strings["status"] = "status";
$a->strings["photo"] = "foto";
$a->strings["%1\$s likes %2\$s's %3\$s"] = "%1\$s curtiu %2\$s que publicou %3\$s";
$a->strings["Welcome to %s"] = "Bem-vindo a %s";

View file

@ -0,0 +1,73 @@
# ADDON communityhome
# Copyright (C)
# This file is distributed under the same license as the Friendica communityhome addon package.
#
#
# Translators:
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-27 05:01-0500\n"
"PO-Revision-Date: 2014-07-08 11:46+0000\n"
"Last-Translator: Arian - Cazare Muncitori <arianserv@gmail.com>\n"
"Language-Team: Romanian (Romania) (http://www.transifex.com/projects/p/friendica/language/ro_RO/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ro_RO\n"
"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n"
#: communityhome.php:28 communityhome.php:34
msgid "Login"
msgstr "Autentificare"
#: communityhome.php:29
msgid "OpenID"
msgstr "OpenID"
#: communityhome.php:39
msgid "Latest users"
msgstr "Cei mai recenți utilizatori"
#: communityhome.php:84
msgid "Most active users"
msgstr "Cei mai activi utilizatori"
#: communityhome.php:102
msgid "Latest photos"
msgstr "Cele mai recente fotografii"
#: communityhome.php:115
msgid "Contact Photos"
msgstr "Fotografiile Contactului"
#: communityhome.php:116
msgid "Profile Photos"
msgstr "Fotografii de Profil"
#: communityhome.php:141
msgid "Latest likes"
msgstr "Cele mai recente aprecieri"
#: communityhome.php:163
msgid "event"
msgstr "eveniment"
#: communityhome.php:166 communityhome.php:175
msgid "status"
msgstr "status"
#: communityhome.php:171
msgid "photo"
msgstr "fotografie"
#: communityhome.php:180
#, php-format
msgid "%1$s likes %2$s's %3$s"
msgstr "%1$s apreciază %3$s lui %2$s"
#: communityhome.php:189
#, php-format
msgid "Welcome to %s"
msgstr "Bine ați venit la %s"

View file

@ -0,0 +1,20 @@
<?php
if(! function_exists("string_plural_select_ro")) {
function string_plural_select_ro($n){
return ($n==1?0:((($n%100>19)||(($n%100==0)&&($n!=0)))?2:1));;
}}
;
$a->strings["Login"] = "Autentificare";
$a->strings["OpenID"] = "OpenID";
$a->strings["Latest users"] = "Cei mai recenți utilizatori";
$a->strings["Most active users"] = "Cei mai activi utilizatori";
$a->strings["Latest photos"] = "Cele mai recente fotografii";
$a->strings["Contact Photos"] = "Fotografiile Contactului";
$a->strings["Profile Photos"] = "Fotografii de Profil";
$a->strings["Latest likes"] = "Cele mai recente aprecieri";
$a->strings["event"] = "eveniment";
$a->strings["status"] = "status";
$a->strings["photo"] = "fotografie";
$a->strings["%1\$s likes %2\$s's %3\$s"] = "%1\$s apreciază %3\$s lui %2\$s";
$a->strings["Welcome to %s"] = "Bine ați venit la %s";

View file

@ -0,0 +1,74 @@
# ADDON communityhome
# Copyright (C)
# This file is distributed under the same license as the Friendica communityhome addon package.
#
#
# Translators:
# Stanislav N. <pztrn@pztrn.name>, 2017
msgid ""
msgstr ""
"Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2013-02-27 05:01-0500\n"
"PO-Revision-Date: 2017-04-08 17:08+0000\n"
"Last-Translator: Stanislav N. <pztrn@pztrn.name>\n"
"Language-Team: Russian (http://www.transifex.com/Friendica/friendica/language/ru/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: ru\n"
"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
#: communityhome.php:28 communityhome.php:34
msgid "Login"
msgstr "Вход"
#: communityhome.php:29
msgid "OpenID"
msgstr "OpenID"
#: communityhome.php:39
msgid "Latest users"
msgstr "Последние пользователи"
#: communityhome.php:84
msgid "Most active users"
msgstr "Самые активные пользователи"
#: communityhome.php:102
msgid "Latest photos"
msgstr "Последние фото"
#: communityhome.php:115
msgid "Contact Photos"
msgstr "Фотографии контакта"
#: communityhome.php:116
msgid "Profile Photos"
msgstr "Фотографии профиля"
#: communityhome.php:141
msgid "Latest likes"
msgstr "Последние отметки \"нравится\""
#: communityhome.php:163
msgid "event"
msgstr "событие"
#: communityhome.php:166 communityhome.php:175
msgid "status"
msgstr "статус"
#: communityhome.php:171
msgid "photo"
msgstr "фото"
#: communityhome.php:180
#, php-format
msgid "%1$s likes %2$s's %3$s"
msgstr "%1$s нравится %3$s от %2$s "
#: communityhome.php:189
#, php-format
msgid "Welcome to %s"
msgstr "Добро пожаловать на %s!"

View file

@ -0,0 +1,20 @@
<?php
if(! function_exists("string_plural_select_ru")) {
function string_plural_select_ru($n){
return ($n%10==1 && $n%100!=11 ? 0 : $n%10>=2 && $n%10<=4 && ($n%100<12 || $n%100>14) ? 1 : $n%10==0 || ($n%10>=5 && $n%10<=9) || ($n%100>=11 && $n%100<=14)? 2 : 3);;
}}
;
$a->strings["Login"] = "Вход";
$a->strings["OpenID"] = "OpenID";
$a->strings["Latest users"] = "Последние пользователи";
$a->strings["Most active users"] = "Самые активные пользователи";
$a->strings["Latest photos"] = "Последние фото";
$a->strings["Contact Photos"] = "Фотографии контакта";
$a->strings["Profile Photos"] = "Фотографии профиля";
$a->strings["Latest likes"] = "Последние отметки \"нравится\"";
$a->strings["event"] = "событие";
$a->strings["status"] = "статус";
$a->strings["photo"] = "фото";
$a->strings["%1\$s likes %2\$s's %3\$s"] = "%1\$s нравится %3\$s от %2\$s ";
$a->strings["Welcome to %s"] = "Добро пожаловать на %s!";

View file

@ -0,0 +1,8 @@
<?php
$a->strings["Login"] = "Logga in";
$a->strings["Contact Photos"] = "Dina kontakters bilder";
$a->strings["Profile Photos"] = "Profilbilder";
$a->strings["status"] = "status";
$a->strings["photo"] = "bild";
$a->strings["Welcome to %s"] = "V&auml;lkommen till %s";

View file

@ -0,0 +1,14 @@
<?php
$a->strings["Login"] = "登录";
$a->strings["OpenID"] = "OpenID";
$a->strings["Latest users"] = "最近用户";
$a->strings["Most active users"] = "最积极用户";
$a->strings["Latest photos"] = "最近照片";
$a->strings["Contact Photos"] = "熟人照片";
$a->strings["Profile Photos"] = "简介照片";
$a->strings["Latest likes"] = "最近喜欢";
$a->strings["event"] = "项目";
$a->strings["status"] = "现状";
$a->strings["photo"] = "照片";
$a->strings["Welcome to %s"] = "%s欢迎你";

View file

@ -0,0 +1,61 @@
<script>
$(function(){
$("#tab_1 a").click(function(e){
$("#login_standard").show();
$("#login_openid").hide();
$("#tab_1").addClass("active");
$("#tab_2").removeClass("active");
e.preventDefault();
return false;
});
$("#tab_2 a").click(function(e){
$("#login_openid").show();
$("#login_standard").hide();
$("#tab_2").addClass("active");
$("#tab_1").removeClass("active");
e.preventDefault();
return false;
});
});
</script>
{{if $noOid}}
<h3>{{$login_title}}</h3>
{{else}}
<ul class="tabs">
<li id="tab_1" class="tab button active"><a href="#">{{$tab_1}}</a></li>
<li id="tab_2" class="tab button"><a href="#">{{$tab_2}}</a></li>
</ul>
{{/if}}
{{$login_form}}
{{if $lastusers_title}}
<h3>{{$lastusers_title}}</h3>
<div class='items-wrapper'>
{{foreach $lastusers_items as $i}}
{{$i}}
{{/foreach}}
</div>
{{/if}}
{{if $photos_title}}
<h3>{{$photos_title}}</h3>
<div class='items-wrapper'>
{{foreach $photos_items as $i}}
{{$i}}
{{/foreach}}
</div>
{{/if}}
{{if $like_title}}
<h3>{{$like_title}}</h3>
<ul id='likes'>
{{foreach $like_items as $i}}
<li>{{$i}}</li>
{{/foreach}}
</ul>
{{/if}}

View file

@ -0,0 +1,10 @@
<div class="directory-item" id="directory-item-{{$id}}" >
<div class="directory-photo-wrapper" id="directory-photo-wrapper-{{$id}}" >
<div class="directory-photo" id="directory-photo-{{$id}}" >
<a href="{{$profile_link}}" class="directory-profile-link" id="directory-profile-link-{{$id}}" >
<img class="directory-photo-img" src="{{$photo}}" alt="{{$photo_user}} {{if $photo_title}}: {{$photo_title}}{{/if}}" title="{{$alt_text}}" />
</a>
</div>
</div>
</div>

View file

@ -0,0 +1,9 @@
<div id="communityhome-wrapper">
{{foreach $fields as $field}}
{{include file="field_checkbox.tpl" field=$field}}
{{/foreach}}
</div>
<div class="settings-submit-wrapper" >
<input type="submit" id="communityhome-submit" name="communityhome-submit" class="settings-submit" value="{{$submit}}" />
</div>

23
dav/Changelog.txt Normal file
View file

@ -0,0 +1,23 @@
v0.3
[REFACTOR] The new version of the VObject Library is used
[REFACTOR] The addressbook part has beed heavily refactored
[REFACTOR] Remove some Friendica-specific code out of the "common"-folder
v0.2.0
======
[FEATURE] Multiple private Calendars can be created. Each calendar can have its own default color; single events of a calendar can override this setting.
[FEATURE] Support for recurring events.
[FEATURE] ICS files can be imported to and exported from a calendar.
[FEATURE] Notification by e-mail is supported.
[COMPATIBILITY] When creating or updating an event using CalDAV, the etag is returned.
v0.1.1
======
[FEATURE] A "New Event" Button in the navigation bar of the calendar is added.
[FEATURE] When creating an event by dragging in the calendar, the "Edit Details"-Link leads to a page where the details can be added before actually creating the event.
[BUGFIX] When editing a event, the start time cannot be set befor the end time anymore.
[BUGFIX] Fixed some problems with Magic Quotes
v0.1.0
======
Initial Release

74
dav/README.md Normal file
View file

@ -0,0 +1,74 @@
# Calendar with CalDAV Support
**THIS ADDON IS UNSUPPORTED**
This is a rewrite of the calendar system used by the german social network [Animexx](http://www.animexx.de/).
It's still in a very early stage, so expect major bugs. Please feel free to report any of them, by mail (cato@animexx.de) or Friendica: http://friendica.hoessl.eu/profile/cato
At the moment, the calendar system supports the following features:
- A web-based drag&drop interface for managing events
- All-Day-Events, Multi-Day-Events, and time-based events
- Giving the subject, a description, a location and a color for the event (the color is not available through CalDAV, though)
- Recurrences (not the whole set of options given in the iCalendar spec, but the most important ones)
- Notification by e-mail. Multiple notifications can be set per event
- Multiple calendars per user
- Access to the events using CalDAV (using iPhone, Thunderbird Lightning etc., see below)
- Read-only access to the friendica-native events (also using CalDAV)
- The friendica-contacts are made available using CardDAV (confirmed to work with iOS)
- The events of a calendar can be exported as ICS file. ICS files can be imported into a calendar
## Internationalization:
- At the moment, settings for the US and the german systems are selectable (regarding the date format and the first day of the week). More will be added on request.
- The basic design of the system is aware of timezones; however this is not reflected in the UI yet. It currently assumes that the timezone set in the friendica-installation matches the user's local time and matches the local time set in the user's operating system.
## CalDAV device compatibility:
- iOS (iPhone/iPodTouch) works
- Thunderbird Lightning works
- Android:
- aCal (http://andrew.mcmillan.net.nz/projects/aCal) works, available in F-Droid and Google Play
- CalDAV-Sync (http://dmfs.org/caldav/) works, non-free
## Installation
After activating, serveral tables in the database have to be created. The admin-interface of the addon will try to do this automatically.
In case of errors, the SQL-statement to create the tables manually are shown in the admin-interface.
## Functuality missing: (a.k.a. "Roadmap")
- Sharing events; all events are private at the moment, therefore this system is not a complete replacement for the friendica-native events
- Attendees / Collaboration
## Used libraries
SabreDAV
http://code.google.com/p/sabredav/
New BSD License
wdCalendar
http://www.web-delicious.com/jquery-plugins/
GNU Lesser General Public License
jQueryUI
http://jqueryui.com/
Dual-licenced: MIT and GPL licenses
TimePicker
http://www.texotela.co.uk/code/jquery/timepicker/
Dual-licenced: MIT and GPL licenses
ColorPicker
http://laktek.com/2008/10/27/really-simple-color-picker-in-jquery/
MIT License
Author of this addon (the parts that are not part of the libraries above):
Tobias Hößl
http://friendica.hoessl.eu/profile/cato
http://www.hoessl.eu/
tobias@hoessl.eu
@TobiasHoessl
Originally developed for:
Animexx e.V. / http://www.animexx.de/

916
dav/SabreDAV/ChangeLog Normal file
View file

@ -0,0 +1,916 @@
1.7.0-alpha (2012-??-??)
* BC Break: The calendarobjects database table has a bunch of new
fields, and a migration script is required to ensure everything will
keep working. Read the wiki for more details.
* BC Break: The iCalendar interface now has a new method: calendarQuery.
* BC Break: In this version a number of classes have been deleted, that
have been previously deprecated. Namely:
- Sabre_DAV_Directory (now: Sabre_DAV_Collection)
- Sabre_DAV_SimpleDirectory (now: Sabre_DAV_SimpleCollection)
- Sabre_VObject_Element_DateTime (now: .._Property_DateTime)
- Sabre_VObject_Element_MultiDateTime (-> .._Property_MultiDateTime)
* BC Break: Sabre_CalDAV_Schedule_IMip::sendMessage now has an extra
argument. If you extended this class, you should fix this method. It's
only used for informational purposes.
* BC Break: The DAV: namespace is no longer converted to urn:DAV. This was
a workaround for a bug in older PHP versions (pre-5.3).
* Changed: The Sabre_VObject library now spawned into it's own project!
* New feature: Support for caldav notifications!
* Changed: Responsibility for dealing with the calendar-query is now
moved from the CalDAV addon to the CalDAV backends. This allows for
heavy optimizations.
* Changed: The CalDAV PDO backend is now a lot faster for common
calendar queries.
* Fixed: Marking both the text/calendar and text/x-vcard as UTF-8
encoded.
* Fixed: Workaround for the SOGO connector, as it doesn't understand
receiving "text/x-vcard; charset=utf-8" for a contenttype.
* Added: Sabre_DAV_Client now throws more specific exceptions in cases
where we already has an exception class.
* Added: Sabre_DAV_PartialUpdate. This addon allows you to use the
PATCH method to update parts of a file.
* Added: Tons of timezone name mappings for Microsoft Exchange.
* Added: Support for an 'exception' event.
* Fixed: Uploaded VCards without a UID are now rejected. (thanks Dominik!)
* Fixed: Rejecting calendar objects if they are not in the
supported-calendar-component list. (thanks Armin!)
* Fixed: Issue 219: serialize() now reorders correctly.
* Fixed: Sabre_DAV_XMLUtil no longer returns empty $dom->childNodes
if there is whitespace in $dom.
1.6.5-stable (2012-??-??)
* Fixed: Workaround for line-ending bug OS X 10.8 addressbook has.
1.6.4-stable (2012-08-02)
* Fixed: Issue 220: Calendar-query filters may fail when filtering on
alarms, if an overridden event has it's alarm removed.
* Fixed: Compatibility for OS/X 10.8 iCal in the IMipHandler.
* Fixed: Issue 222: beforeWriteContent shouldn't be called for lock
requests.
* Fixed: Problem with POST requests to the outbox if mailto: was not lower
cased.
* Fixed: Yearly recurrence rule expansion on leap-days no behaves
correctly.
* Fixed: Correctly checking if recurring, all-day events with no dtstart
fall in a timerange if the start of the time-range exceeds the start of
the instance of an event, but not the end.
* Fixed: All-day recurring events wouldn't match if an occurence ended
exactly on the start of a time-range.
* Fixed: HTTP basic auth did not correctly deal with passwords containing
colons on some servers.
* Fixed: Issue 228: DTEND is now non-inclusive for all-day events in the
calendar-query REPORT and free-busy calculations.
1.6.3-stable (2012-06-12)
* Added: It's now possible to specify in Sabre_DAV_Client which type of
authentication is to be used.
* Fixed: Issue 206: Sabre_DAV_Client PUT requests are fixed.
* Fixed: Issue 205: Parsing an iCalendar 0-second date interval.
* Fixed: Issue 112: Stronger validation of iCalendar objects. Now making
sure every iCalendar object only contains 1 component, and disallowing
vcards, forcing every component to have a UID.
* Fixed: Basic validation for vcards in the CardDAV addon.
* Fixed: Issue 213: Workaround for an Evolution bug, that prevented it
from updating events.
* Fixed: Issue 211: A time-limit query on a non-relative alarm trigger in
a recurring event could result in an endless loop.
* Fixed: All uri fields are now a maximum of 200 characters. The Bynari
outlook addon used much longer strings so this should improve
compatibility.
* Fixed: Added a workaround for a bug in KDE 4.8.2 contact syncing. See
https://bugs.kde.org/show_bug.cgi?id=300047
* Fixed: Issue 217: Sabre_DAV_Tree_FileSystem was pretty broken.
1.6.2-stable (2012-04-16)
* Fixed: Sabre_VObject_Node::$parent should have been public.
* Fixed: Recurrence rules of events are now taken into consideration when
doing time-range queries on alarms.
* Fixed: Added a workaround for the fact that php's DateInterval cannot
parse weeks and days at the same time.
* Added: Sabre_DAV_Server::$exposeVersion, allowing you to hide SabreDAV's
version number from various outputs.
* Fixed: DTSTART values would be incorrect when expanding events.
* Fixed: DTSTART and DTEND would be incorrect for expansion of WEEKLY
BYDAY recurrences.
* Fixed: Issue 203: A problem with overridden events hitting the exact
date and time of a subsequent event in the recurrence set.
* Fixed: There was a problem with recurrence rules, for example the 5th
tuesday of the month, if this day did not exist.
* Added: New HTTP status codes from draft-nottingham-http-new-status-04.
1.6.1-stable (2012-03-05)
* Added: createFile and put() can now return an ETag.
* Added: Sending back an ETag on for operations on CardDAV backends. This
should help with OS X 10.6 Addressbook compatibility.
* Fixed: Fixed a bug where an infinite loop could occur in the recurrence
iterator if the recurrence was YEARLY, with a BYMONTH rule, and either
BYDAY or BYMONTHDAY match the first day of the month.
* Fixed: Events that are excluded using EXDATE are still counted in the
COUNT= parameter in the RRULE property.
* Added: Support for time-range filters on VALARM components.
* Fixed: Correctly filtering all-day events.
* Fixed: Sending back correct mimetypes from the browser addon (thanks
Jürgen).
* Fixed: Issue 195: Sabre_CardDAV pear package had an incorrect dependency.
* Fixed: Calendardata would be destroyed when performing a MOVE request.
1.6.0-stable (2012-02-22)
* BC Break: Now requires PHP 5.3
* BC Break: Any node that implemented Sabre_DAVACL_IACL must now also
implement the getSupportedPrivilegeSet method. See website for details.
* BC Break: Moved functions from Sabre_CalDAV_XMLUtil to
Sabre_VObject_DateTimeParser.
* BC Break: The Sabre_DAVACL_IPrincipalCollection now has two new methods:
'searchPrincipals' and 'updatePrincipal'.
* BC Break: Sabre_DAV_ILockable is removed and all related per-node
locking functionality.
* BC Break: Sabre_DAV_Exception_FileNotFound is now deprecated in favor of
Sabre_DAV_Exception_NotFound. The former will be removed in a later
version.
* BC Break: Removed Sabre_CalDAV_ICalendarUtil, use Sabre_VObject instead.
* BC Break: Sabre_CalDAV_Server is now deprecated, check out the
documentation on how to setup a caldav server with just
Sabre_DAV_Server.
* BC Break: Default Principals PDO backend now needs a new field in the
'principals' table. See the website for details.
* Added: Ability to create new calendars and addressbooks from within the
browser addon.
* Added: Browser addon: icons for various nodes.
* Added: Support for FREEBUSY reports!
* Added: Support for creating principals with admin-level privileges.
* Added: Possibility to let server send out invitation emails on behalf of
CalDAV client, using Sabre_CalDAV_Schedule_IMip.
* Changed: beforeCreateFile event now passes data argument by reference.
* Changed: The 'propertyMap' property from Sabre_VObject_Reader, must now
be specified in Sabre_VObject_Property::$classMap.
* Added: Ability for addons to tell the ACL addon which principal
addons are searchable.
* Added: [DAVACL] Per-node overriding of supported privileges. This allows
for custom privileges where needed.
* Added: [DAVACL] Public 'principalSearch' method on the DAVACL addon,
which allows for easy searching for principals, based on their
properties.
* Added: Sabre_VObject_Component::getComponents() to return a list of only
components and not properties.
* Added: An includes.php file in every sub-package (CalDAV, CardDAV, DAV,
DAVACL, HTTP, VObject) as an alternative to the autoloader. This often
works much faster.
* Added: Support for the 'Me card', which allows Addressbook.app users
specify which vcard is their own.
* Added: Support for updating principal properties in the DAVACL principal
backends.
* Changed: Major refactoring in the calendar-query REPORT code. Should
make things more flexible and correct.
* Changed: The calendar-proxy-[read|write] principals will now only appear
in the tree, if they actually exist in the Principal backend. This should
reduce some problems people have been having with this.
* Changed: Sabre_VObject_Element_* classes are now renamed to
Sabre_VObject_Property. Old classes are retained for backwards
compatibility, but this will be removed in the future.
* Added: Sabre_VObject_FreeBusyGenerator to generate free-busy reports
based on lists of events.
* Added: Sabre_VObject_RecurrenceIterator to find all the dates and times
for recurring events.
* Fixed: Issue 97: Correctly handling RRULE for the calendar-query REPORT.
* Fixed: Issue 154: Encoding of VObject parameters with no value was
incorrect.
* Added: Support for {DAV:}acl-restrictions property from RFC3744.
* Added: The contentlength for calendar objects can now be supplied by a
CalDAV backend, allowing for more optimizations.
* Fixed: Much faster implementation of Sabre_DAV_URLUtil::encodePath.
* Fixed: {DAV:}getcontentlength may now be not specified.
* Fixed: Issue 66: Using rawurldecode instead of urldecode to decode paths
from clients. This means that + will now be treated as a literal rather
than a space, and this should improve compatibility with the Windows
built-in client.
* Added: Sabre_DAV_Exception_PaymentRequired exception, to emit HTTP 402
status codes.
* Added: Some mysql unique constraints to example files.
* Fixed: Correctly formatting HTTP dates.
* Fixed: Issue 94: Sending back Last-Modified header for 304 responses.
* Added: Sabre_VObject_Component_VEvent, Sabre_VObject_Component_VJournal,
Sabre_VObject_Component_VTodo and Sabre_VObject_Component_VCalendar.
* Changed: Properties are now also automatically mapped to their
appropriate classes, if they are created using the add() or __set()
methods.
* Changed: Cloning VObject objects now clones the entire tree, rather than
just the default shallow copy.
* Added: Support for recurrence expansion in the CALDAV:calendar-multiget
and CALDAV:calendar-query REPORTS.
* Changed: CalDAV PDO backend now sorts calendars based on the internal
'calendarorder' field.
* Added: Issue 181: Carddav backends may no optionally not supply the carddata in
getCards, if etag and size are specified. This may speed up certain
requests.
* Added: More arguments to beforeWriteContent and beforeCreateFile (see
WritingPlugins wiki document).
* Added: Hook for iCalendar validation. This allows us to validate
iCalendar objects when they're uploaded. At the moment we're just
validating syntax.
* Added: VObject now support Windows Timezone names correctly (thanks
mrpace2).
* Added: If a timezonename could not be detected, we fall back on the
default PHP timezone.
* Added: Now a Composer package (thanks willdurand).
* Fixed: Support for \N as a newline character in the VObject reader.
* Added: afterWriteContent, afterCreateFile and afterUnbind events.
* Added: Postgresql example files. Not part of the unittests though, so
use at your own risk.
* Fixed: Issue 182: Removed backticks from sql queries, so it will work
with Postgres.
1.5.9-stable (2012-04-16)
* Fixed: Issue with parsing timezone identifiers that were surrounded by
quotes. (Fixes emClient compatibility).
1.5.8-stable (2012-02-22)
* Fixed: Issue 95: Another timezone parsing issue, this time in
calendar-query.
1.5.7-stable (2012-02-19)
* Fixed: VObject properties are now always encoded before components.
* Fixed: Sabre_DAVACL had issues with multiple levels of privilege
aggregration.
* Changed: Added 'GuessContentType' addon to fileserver.php example.
* Fixed: The Browser addon will now trigger the correct events when
creating files.
* Fixed: The ICSExportPlugin now considers ACL's.
* Added: Made it optional to supply carddata from an Addressbook backend
when requesting getCards. This can make some operations much faster, and
could result in much lower memory use.
* Fixed: Issue 187: Sabre_DAV_UUIDUtil was missing from includes file.
* Fixed: Issue 191: beforeUnlock was triggered twice.
1.5.6-stable (2012-01-07)
* Fixed: Issue 174: VObject could break UTF-8 characters.
* Fixed: pear package installation issues.
1.5.5-stable (2011-12-16)
* Fixed: CalDAV time-range filter workaround for recurring events.
* Fixed: Bug in Sabre_DAV_Locks_Backend_File that didn't allow multiple
files to be locked at the same time.
1.5.4-stable (2011-10-28)
* Fixed: GuessContentType addon now supports mixed case file extensions.
* Fixed: DATE-TIME encoding was wrong in VObject. (we used 'DATETIME').
* Changed: Sending back HTTP 204 after a PUT request on an existing resource
instead of HTTP 200. This should fix Evolution CardDAV client
compatibility.
* Fixed: Issue 95: Parsing X-LIC-LOCATION if it's available.
* Added: All VObject elements now have a reference to their parent node.
1.5.3-stable (2011-09-28)
* Fixed: Sabre_DAV_Collection was missing from the includes file.
* Fixed: Issue 152. iOS 1.4.2 apparantly requires HTTP/1.1 200 OK to be in
uppercase.
* Fixed: Issue 153: Support for files with mixed newline styles in
Sabre_VObject.
* Fixed: Issue 159: Automatically converting any vcard and icalendardata
to UTF-8.
* Added: Sabre_DAV_SimpleFile class for easy static file creation.
* Added: Issue 158: Support for the CARDDAV:supported-address-data
property.
1.5.2-stable (2011-09-21)
* Fixed: carddata and calendardata MySQL fields are now of type
'mediumblob'. 'TEXT' was too small sometimes to hold all the data.
* Fixed: {DAV:}supported-report-set is now correctly reporting the reports
for IAddressBook.
* Added: Sabre_VObject_Property::add() to add duplicate parameters to
properties.
* Added: Issue 151: Sabre_CalDAV_ICalendar and Sabre_CalDAV_ICalendarObject
interfaces.
* Fixed: Issue 140: Not returning 201 Created if an event cancelled the
creation of a file.
* Fixed: Issue 150: Faster URLUtil::encodePath() implementation.
* Fixed: Issue 144: Browser addon could interfere with
TemporaryFileFilterPlugin if it was loaded first.
* Added: It's not possible to specify more 'alternate uris' in principal
backends.
1.5.1-stable (2011-08-24)
* Fixed: Issue 137. Hiding action interface in HTML browser for
non-collections.
* Fixed: addressbook-query is now correctly returned from the
{DAV:}supported-report-set property.
* Fixed: Issue 142: Bugs in groupwareserver.php example.
* Fixed: Issue 139: Rejecting PUT requests with Content-Range.
1.5.0-stable (2011-08-12)
* Added: CardDAV support.
* Added: An experimental WebDAV client.
* Added: MIME-Directory grouping support in the VObject library. This is
very useful for people attempting to parse vcards.
* BC Break: Adding parameters with the VObject libraries now overwrites
the previous parameter, rather than just add it. This makes more sense
for 99% of the cases.
* BC Break: lib/Sabre.autoload.php is now removed in favor of
lib/Sabre/autoload.php.
* Deprecated: Sabre_DAV_Directory is now deprecated and will be removed in
a future version. Use Sabre_DAV_Collection instead.
* Deprecated: Sabre_DAV_SimpleDirectory is now deprecated and will be
removed in a future version. Use Sabre_DAV_SimpleCollection instead.
* Fixed: Problem with overriding tablenames for the CalDAV backend.
* Added: Clark-notation parser to XML utility.
* Added: unset() support to VObject components.
* Fixed: Refactored CalDAV property fetching to be faster and simpler.
* Added: Central string-matcher for CalDAV and CardDAV addons.
* Added: i;unicode-casemap support
* Fixed: VObject bug: wouldn't parse parameters if they weren't specified
in uppercase.
* Fixed: VObject bug: Parameters now behave more like Properties.
* Fixed: VObject bug: Parameters with no value are now correctly parsed.
* Changed: If calendars don't specify which components they allow, 'all'
components are assumed (e.g.: VEVENT, VTODO, VJOURNAL).
* Changed: Browser addon now uses POST variable 'sabreAction' instead of
'action' to reduce the chance of collisions.
1.4.4-stable (2011-07-07)
* Fixed: Issue 131: Custom CalDAV backends could break in certain cases.
* Added: The option to override the default tablename all PDO backends
use. (Issue 60).
* Fixed: Issue 124: 'File' authentication backend now takes realm into
consideration.
* Fixed: Sabre_DAV_Property_HrefList now properly deserializes. This
allows users to update the {DAV:}group-member-set property.
* Added: Helper functions for DateTime-values in Sabre_VObject package.
* Added: VObject library can now automatically map iCalendar properties to
custom classes.
1.4.3-stable (2011-04-25)
* Fixed: Issue 123: Added workaround for Windows 7 UNLOCK bug.
* Fixed: datatype of lastmodified field in mysql.calendars.sql. Please
change the DATETIME field to an INT to ensure this field will work
correctly.
* Change: Sabre_DAV_Property_Principal is now renamed to
Sabre_DAVACL_Property_Principal.
* Added: API level support for ACL HTTP method.
* Fixed: Bug in serializing {DAV:}acl property.
* Added: deserializer for {DAV:}resourcetype property.
* Added: deserializer for {DAV:}acl property.
* Added: deserializer for {DAV:}principal property.
1.4.2-beta (2011-04-01)
* Added: It's not possible to disable listing of nodes that are denied
read access by ACL.
* Fixed: Changed a few properties in CalDAV classes from private to
protected.
* Fixed: Issue 119: Terrible things could happen when relying on
guessBaseUri, the server was running on the root of the domain and a user
tried to access a file ending in .php. This is a slight BC break.
* Fixed: Issue 118: Lock tokens in If headers without a uri should be
treated as the request uri, not 'all relevant uri's.
* Fixed: Issue 120: PDO backend was incorrectly fetching too much locks in
cases where there were similar named locked files in a directory.
1.4.1-beta (2011-02-26)
* Fixed: Sabre_DAV_Locks_Backend_PDO returned too many locks.
* Fixed: Sabre_HTTP_Request::getHeader didn't return Content-Type when
running on apache, so a few workarounds were added.
* Change: Slightly changed CalDAV Backend API's, to allow for heavy
optimizations. This is non-bc breaking.
1.4.0-beta (2011-02-12)
* Added: Partly RFC3744 ACL support.
* Added: Calendar-delegation (caldav-proxy) support.
* BC break: In order to fix Issue 99, a new argument had to be added to
Sabre_DAV_Locks_Backend_*::getLocks classes. Consult the classes for
details.
* Deprecated: Sabre_DAV_Locks_Backend_FS is now deprecated and will be
removed in a later version. Use PDO or the new File class instead.
* Deprecated: The Sabre_CalDAV_ICalendarUtil class is now marked
deprecated, and will be removed in a future version. Please use
Sabre_VObject instead.
* Removed: All principal-related functionality has been removed from the
Sabre_DAV_Auth_Plugin, and moved to the Sabre_DAVACL_Plugin.
* Added: VObject library, for easy vcard/icalendar parsing using a natural
interface.
* Added: Ability to automatically generate full .ics feeds off calendars.
To use: Add the Sabre_CalDAV_ICSExportPlugin, and add ?export to your
calendar url.
* Added: Plugins can now specify a addonname, for easy access using
Sabre_DAV_Server::getPlugin().
* Added: beforeGetProperties event.
* Added: updateProperties event.
* Added: Principal listings and calendar-access can now be done privately,
disallowing users from accessing or modifying other users' data.
* Added: You can now pass arrays to the Sabre_DAV_Server constructor. If
it's an array with node-objects, a Root collection will automatically be
created, and the nodes are used as top-level children.
* Added: The principal base uri is now customizable. It used to be
hardcoded to 'principals/[user]'.
* Added: getSupportedReportSet method in ServerPlugin class. This allows
you to easily specify which reports you're implementing.
* Added: A '..' link to the HTML browser.
* Fixed: Issue 99: Locks on child elements were ignored when their parent
nodes were deleted.
* Fixed: Issue 90: lockdiscovery property and LOCK response now include a
{DAV}lockroot element.
* Fixed: Issue 96: support for 'default' collation in CalDAV text-match
filters.
* Fixed: Issue 102: Ensuring that copy and move with identical source and
destination uri's fails.
* Fixed: Issue 105: Supporting MKCALENDAR with no body.
* Fixed: Issue 109: Small fixes in Sabre_HTTP_Util.
* Fixed: Issue 111: Properly catching the ownername in a lock (if it's a
string)
* Fixed: Sabre_DAV_ObjectTree::nodeExist always returned false for the
root node.
* Added: Global way to easily supply new resourcetypes for certain node
classes.
* Fixed: Issue 59: Allowing the user to override the authentication realm
in Sabre_CalDAV_Server.
* Update: Issue 97: Looser time-range checking if there's a recurrence
rule in an event. This fixes 'missing recurring events'.
1.3.0 (2010-10-14)
* Added: childExists method to Sabre_DAV_ICollection. This is an api
break, so if you implement Sabre_DAV_ICollection directly, add the method.
* Changed: Almost all HTTP method implementations now take a uri argument,
including events. This allows for internal rerouting of certain calls.
If you have custom addons, make sure they use this argument. If they
don't, they will likely still work, but it might get in the way of
future changes.
* Changed: All getETag methods MUST now surround the etag with
double-quotes. This was a mistake made in all previous SabreDAV
versions. If you don't do this, any If-Match, If-None-Match and If:
headers using Etags will work incorrectly. (Issue 85).
* Added: Sabre_DAV_Auth_Backend_AbstractBasic class, which can be used to
easily implement basic authentication.
* Removed: Sabre_DAV_PermissionDenied class. Use Sabre_DAV_Forbidden
instead.
* Removed: Sabre_DAV_IDirectory interface, use Sabre_DAV_ICollection
instead.
* Added: Browser addon now uses {DAV:}displayname if this property is
available.
* Added: Cache layer in the ObjectTree.
* Added: Tree classes now have a delete and getChildren method.
* Fixed: If-Modified-Since and If-Unmodified-Since would be incorrect if
the date is an exact match.
* Fixed: Support for multiple ETags in If-Match and If-None-Match headers.
* Fixed: Improved baseUrl handling.
* Fixed: Issue 67: Non-seekable stream support in ::put()/::get().
* Fixed: Issue 65: Invalid dates are now ignored.
* Updated: Refactoring in Sabre_CalDAV to make everything a bit more
ledgable.
* Fixed: Issue 88, Issue 89: Fixed compatibility for running SabreDAV on
Windows.
* Fixed: Issue 86: Fixed Content-Range top-boundary from 'file size' to
'file size'-1.
1.2.4 (2010-07-13)
* Fixed: Issue 62: Guessing baseUrl fails when url contains a
query-string.
* Added: Apache configuration sample for CGI/FastCGI setups.
* Fixed: Issue 64: Only returning calendar-data when it was actually
requested.
1.2.3 (2010-06-26)
* Fixed: Issue 57: Supporting quotes around etags in If-Match and
If-None-Match
1.2.2 (2010-06-21)
* Updated: SabreDAV now attempts to guess the BaseURI if it's not set.
* Updated: Better compatibility with BitKinex
* Fixed: Issue 56: Incorrect behaviour for If-None-Match headers and GET
requests.
* Fixed: Issue with certain encoded paths in Browser Plugin.
1.2.1 (2010-06-07)
* Fixed: Issue 50, patch by Mattijs Hoitink.
* Fixed: Issue 51, Adding windows 7 lockfiles to TemporaryFileFilter.
* Fixed: Issue 38, Allowing custom filters to be added to
TemporaryFileFilter.
* Fixed: Issue 53, ETags in the If: header were always failing. This
behaviour is now corrected.
* Added: Apache Authentication backend, in case authentication through
.htaccess is desired.
* Updated: Small improvements to example files.
1.2.0 (2010-05-24)
* Fixed: Browser addon now displays international characters.
* Changed: More properties in CalDAV classes are now protected instead of
private.
1.2.0beta3 (2010-05-14)
* Fixed: Custom properties were not properly sent back for allprops
requests.
* Fixed: Issue 49, incorrect parsing of PROPPATCH, affecting Office 2007.
* Changed: Removed CalDAV items from includes.php, and added a few missing
ones.
1.2.0beta2 (2010-05-04)
* Fixed: Issue 46: Fatal error for some non-existent nodes.
* Updated: some example sql to include email address.
* Added: 208 and 508 statuscodes from RFC5842.
* Added: Apache2 configuration examples
1.2.0beta1 (2010-04-28)
* Fixed: redundant namespace declaration in resourcetypes.
* Fixed: 2 locking bugs triggered by litmus when no Sabre_DAV_ILockable
interface is used.
* Changed: using http://sabredav.org/ns for all custom xml properties.
* Added: email address property to principals.
* Updated: CalendarObject validation.
1.2.0alpha4 (2010-04-24)
* Added: Support for If-Range, If-Match, If-None-Match, If-Modified-Since,
If-Unmodified-Since.
* Changed: Brand new build system. Functionality is split up between
Sabre, Sabre_HTTP, Sabre_DAV and Sabre_CalDAV packages. In addition to
that a new non-pear package will be created with all this functionality
combined.
* Changed: Autoloader moved to Sabre/autoload.php.
* Changed: The Allow: header is now more accurate, with appropriate HTTP
methods per uri.
* Changed: Now throwing back Sabre_DAV_Exception_MethodNotAllowed on a few
places where Sabre_DAV_Exception_NotImplemented was used.
1.2.0alpha3 (2010-04-20)
* Update: Complete rewrite of property updating. Now easier to use and
atomic.
* Fixed: Issue 16, automatically adding trailing / to baseUri.
* Added: text/plain is used for .txt files in GuessContentType addon.
* Added: support for principal-property-search and
principal-search-property-set reports.
* Added: Issue 31: Hiding exception information by default. Can be turned
on with the Sabre_DAV_Server::$debugExceptions property.
1.2.0alpha2 (2010-04-08)
* Added: Calendars are now private and can only be read by the owner.
* Fixed: double namespace declaration in multistatus responses.
* Added: MySQL database dumps. MySQL is now also supported next to SQLite.
* Added: expand-properties REPORT from RFC 3253.
* Added: Sabre_DAV_Property_IHref interface for properties exposing urls.
* Added: Issue 25: Throwing error on broken Finder behaviour.
* Changed: Authentication backend is now aware of current user.
1.2.0alpha1 (2010-03-31)
* Fixed: Issue 26: Workaround for broken GVFS behaviour with encoded
special characters.
* Fixed: Issue 34: Incorrect Lock-Token response header for LOCK. Fixes
Office 2010 compatibility.
* Added: Issue 35: SabreDAV version to header to OPTIONS response to ease
debugging.
* Fixed: Issue 36: Incorrect variable name, throwing error in some
requests.
* Fixed: Issue 37: Incorrect smultron regex in temporary filefilter.
* Fixed: Issue 33: Converting ISO-8859-1 characters to UTF-8.
* Fixed: Issue 39 & Issue 40: Basename fails on non-utf-8 locales.
* Added: More unittests.
* Added: SabreDAV version to all error responses.
* Added: URLUtil class for decoding urls.
* Changed: Now using pear.sabredav.org pear channel.
* Changed: Sabre_DAV_Server::getCopyAndMoveInfo is now a public method.
1.1.2-alpha (2010-03-18)
* Added: RFC5397 - current-user-principal support.
* Fixed: Issue 27: encoding entities in property responses.
* Added: naturalselection script now allows the user to specify a 'minimum
number of bytes' for deletion. This should reduce load due to less
crawling
* Added: Full support for the calendar-query report.
* Added: More unittests.
* Added: Support for complex property deserialization through the static
::unserialize() method.
* Added: Support for modifying calendar-component-set
* Fixed: Issue 29: Added TIMEOUT_INFINITE constant
1.1.1-alpha (2010-03-11)
* Added: RFC5689 - Extended MKCOL support.
* Fixed: Evolution support for CalDAV.
* Fixed: PDO-locks backend was pretty much completely broken. This is
100% unittested now.
* Added: support for ctags.
* Fixed: Comma's between HTTP methods in 'Allow' method.
* Changed: default argument for Sabre_DAV_Locks_Backend_FS. This means a
datadirectory must always be specified from now on.
* Changed: Moved Sabre_DAV_Server::parseProps to
Sabre_DAV_XMLUtil::parseProperties.
* Changed: Sabre_DAV_IDirectory is now Sabre_DAV_ICollection.
* Changed: Sabre_DAV_Exception_PermissionDenied is now
Sabre_DAV_Exception_Forbidden.
* Changed: Sabre_CalDAV_ICalendarCollection is removed.
* Added: Sabre_DAV_IExtendedCollection.
* Added: Many more unittests.
* Added: support for calendar-timezone property.
1.1.0-alpha (2010-03-01)
* Note: This version is forked from version 1.0.5, so release dates may be
out of order.
* Added: CalDAV - RFC 4791
* Removed: Sabre_PHP_Exception. PHP has a built-in ErrorException for
this.
* Added: PDO authentication backend.
* Added: Example sql for auth, caldav, locks for sqlite.
* Added: Sabre_DAV_Browser_GuessContentType addon
* Changed: Authentication addon refactored, making it possible to
implement non-digest authentication.
* Fixed: Better error display in browser addon.
* Added: Support for {DAV:}supported-report-set
* Added: XML utility class with helper functions for the WebDAV protocol.
* Added: Tons of unittests
* Added: PrincipalCollection and Principal classes
* Added: Sabre_DAV_Server::getProperties for easy property retrieval
* Changed: {DAV:}resourceType defaults to 0
* Changed: Any non-null resourceType now gets a / appended to the href
value. Before this was just for {DAV:}collection's, but this is now also
the case for for example {DAV:}principal.
* Changed: The Href property class can now optionally create non-relative
uri's.
* Changed: Sabre_HTTP_Response now returns false if headers are already
sent and header-methods are called.
* Fixed: Issue 19: HEAD requests on Collections
* Fixed: Issue 21: Typo in Sabre_DAV_Property_Response
* Fixed: Issue 18: Doesn't work with Evolution Contacts
1.0.15-stable (2010-05-28)
* Added: Issue 31: Hiding exception information by default. Can be turned
on with the Sabre_DAV_Server::$debugExceptions property.
* Added: Moved autoload from lib/ to lib/Sabre/autoload.php. This is also
the case in the upcoming 1.2.0, so it will improve future compatibility.
1.0.14-stable (2010-04-15)
* Fixed: double namespace declaration in multistatus responses.
1.0.13-stable (2010-03-30)
* Fixed: Issue 40: Last references to basename/dirname
1.0.12-stable (2010-03-30)
* Fixed: Issue 37: Incorrect smultron regex in temporary filefilter.
* Fixed: Issue 26: Workaround for broken GVFS behaviour with encoded
special characters.
* Fixed: Issue 33: Converting ISO-8859-1 characters to UTF-8.
* Fixed: Issue 39: Basename fails on non-utf-8 locales.
* Added: More unittests.
* Added: SabreDAV version to all error responses.
* Added: URLUtil class for decoding urls.
* Updated: Now using pear.sabredav.org pear channel.
1.0.11-stable (2010-03-23)
* Non-public release. This release is identical to 1.0.10, but it is used
to test releasing packages to pear.sabredav.org.
1.0.10-stable (2010-03-22)
* Fixed: Issue 34: Invalid Lock-Token header response.
* Added: Issue 35: Addign SabreDAV version to HTTP OPTIONS responses.
1.0.9-stable (2010-03-19)
* Fixed: Issue 27: Entities not being encoded in PROPFIND responses.
* Fixed: Issue 29: Added missing TIMEOUT_INFINITE constant.
1.0.8-stable (2010-03-03)
* Fixed: Issue 21: typos causing errors
* Fixed: Issue 23: Comma's between methods in Allow header.
* Added: Sabre_DAV_ICollection interface, to aid in future compatibility.
* Added: Sabre_DAV_Exception_Forbidden exception. This will replace
Sabre_DAV_Exception_PermissionDenied in the future, and can already be
used to ensure future compatibility.
1.0.7-stable (2010-02-24)
* Fixed: Issue 19 regression for MS Office
1.0.6-stable (2010-02-23)
* Fixed: Issue 19: HEAD requests on Collections
1.0.5-stable (2010-01-22)
* Fixed: Fatal error when a malformed url was used for unlocking, in
conjuction with Sabre.autoload.php due to a incorrect filename.
* Fixed: Improved unittests and build system
1.0.4-stable (2010-01-11)
* Fixed: needed 2 different releases. One for googlecode and one for
pearfarm. This is to retain the old method to install SabreDAV until
pearfarm becomes the standard installation method.
1.0.3-stable (2010-01-11)
* Added: RFC4709 support (davmount)
* Added: 6 unittests
* Added: naturalselection. A tool to keep cache directories below a
specified theshold.
* Changed: Now using pearfarm.org channel server.
1.0.1-stable (2009-12-22)
* Fixed: Issue 15: typos in examples
* Fixed: Minor pear installation issues
1.0.0-stable (2009-11-02)
* Added: SimpleDirectory class. This class allows creating static
directory structures with ease.
* Changed: Custom complex properties and exceptions now get an instance of
Sabre_DAV_Server as their first argument in serialize()
* Changed: Href complex property now prepends server's baseUri
* Changed: delete before an overwriting copy/move is now handles by server
class instead of tree classes
* Changed: events must now explicitly return false to stop execution.
Before, execution would be stopped by anything loosely evaluating to
false.
* Changed: the getPropertiesForPath method now takes a different set of
arguments, and returns a different response. This allows addon
developers to return statuses for properties other than 200 and 404. The
hrefs are now also always calculated relative to the baseUri, and not
the uri of the request.
* Changed: generatePropFindResponse is renamed to generateMultiStatus, and
now takes a list of properties similar to the response of
getPropertiesForPath. This was also needed to improve flexibility for
addon development.
* Changed: Auth addons are no longer included. They were not yet stable
quality, so they will probably be reintroduced in a later version.
* Changed: PROPPATCH also used generateMultiStatus now.
* Removed: unknownProperties event. This is replaced by the
afterGetProperties event, which should provide more flexibility.
* Fixed: Only calling getSize() on IFile instances in httpHead()
* Added: beforeBind event. This is invoked upon file or directory creation
* Added: beforeWriteContent event, this is invoked by PUT and LOCK on an
existing resource.
* Added: beforeUnbind event. This is invoked right before deletion of any
resource.
* Added: afterGetProperties event. This event can be used to make
modifications to property responses.
* Added: beforeLock and beforeUnlock events.
* Added: afterBind event.
* Fixed: Copy and Move could fail in the root directory. This is now
fixed.
* Added: Plugins can now be retrieved by their classname. This is useful
for inter-addon communication.
* Added: The Auth backend can now return usernames and user-id's.
* Added: The Auth backend got a getUsers method
* Added: Sabre_DAV_FSExt_Directory now returns quota info
0.12.1-beta (2009-09-11)
* Fixed: UNLOCK bug. Unlock didn't work at all
0.12-beta (2009-09-10)
* Updated: Browser addon now shows multiple {DAV:}resourcetype values
if available.
* Added: Experimental PDO backend for Locks Manager
* Fixed: Sending Content-Length: 0 for every empty response. This
improves NGinx compatibility.
* Fixed: Last modification time is reported in UTC timezone. This improves
Finder compatibility.
0.11-beta (2009-08-11)
* Updated: Now in Beta
* Updated: Pear package no longer includes docs/ directory. These just
contained rfc's, which are publically available. This reduces the
package from ~800k to ~60k
* Added: generatePropfindResponse now takes a baseUri argument
* Added: ResourceType property can now contain multiple resourcetypes.
* Fixed: Issue 13.
0.10-alpha (2009-08-03)
* Added: Plugin to automatically map GET requests to non-files to
PROPFIND (Sabre_DAV_Browser_MapGetToPropFind). This should allow
easier debugging of complicated WebDAV setups.
* Added: Sabre_DAV_Property_Href class. For future use.
* Added: Ability to choose to use auth-int, auth or both for HTTP Digest
authentication. (Issue 11)
* Changed: Made more methods in Sabre_DAV_Server public.
* Fixed: TemporaryFileFilter addon now intercepts HTTP LOCK requests
to non-existent files. (Issue 12)
* Added: Central list of defined xml namespace prefixes. This can reduce
Bandwidth and legibility for xml bodies with user-defined namespaces.
* Added: now a PEAR-compatible package again, thanks to Michael Gauthier
* Changed: moved default copy and move logic from ObjectTree to Tree class
0.9-alpha (2009-07-21)
* Changed: Major refactoring, removed most of the logic from the Tree
objects. The Server class now directly works with the INode, IFile
and IDirectory objects. If you created your own Tree objects,
this will most likely break in this release.
* Changed: Moved all the Locking logic from the Tree and Server classes
into a separate addon.
* Changed: TemporaryFileFilter is now a addon.
* Added: Comes with an autoloader script. This can be used instead of
the includer script, and is preferred by some people.
* Added: AWS Authentication class.
* Added: simpleserversetup.py script. This will quickly get a fileserver
up and running.
* Added: When subscribing to events, it is now possible to supply a
priority. This is for example needed to ensure that the Authentication
Plugin is used before any other Plugin.
* Added: 22 new tests.
* Added: Users-manager addon for .htdigest files. Experimental and
subject to change.
* Added: RFC 2324 HTTP 418 status code
* Fixed: Exclusive locks could in some cases be picked up as shared locks
* Fixed: Digest auth for non-apache servers had a bug (still not actually
tested this well).
0.8-alpha (2009-05-30)
* Changed: Renamed all exceptions! This is a compatibility break. Every
Exception now follows Sabre_DAV_Exception_FileNotFound convention
instead of Sabre_DAV_FileNotFoundException.
* Added: Browser addon now allows uploading and creating directories
straight from the browser.
* Added: 12 more unittests
* Fixed: Locking bug, which became prevalent on Windows Vista.
* Fixed: Netdrive support
* Fixed: TemporaryFileFilter filtered out too many files. Fixed some
of the regexes.
* Fixed: Added README and ChangeLog to package
0.7-alpha (2009-03-29)
* Added: System to return complex properties from PROPFIND.
* Added: support for {DAV:}supportedlock.
* Added: support for {DAV:}lockdiscovery.
* Added: 6 new tests.
* Added: New addon system.
* Added: Simple HTML directory addon, for browser access.
* Added: Server class now sends back standard pre-condition error xml
bodies. This was new since RFC4918.
* Added: Sabre_DAV_Tree_Aggregrate, which can 'host' multiple Tree objects
into one.
* Added: simple basis for HTTP REPORT method. This method is not used yet,
but can be used by addons to add reports.
* Changed: ->getSize is only called for files, no longer for collections.
r303
* Changed: Sabre_DAV_FilterTree is now Sabre_DAV_Tree_Filter
* Changed: Sabre_DAV_TemporaryFileFilter is now called
Sabre_DAV_Tree_TemporaryFileFilter.
* Changed: removed functions (get(/set)HTTPRequest(/Response)) from Server
class, and using a public property instead.
* Fixed: bug related to parsing proppatch and propfind requests. Didn't
show up in most clients, but it needed fixing regardless. (r255)
* Fixed: auth-int is now properly supported within HTTP Digest.
* Fixed: Using application/xml for a mimetype vs. text/xml as per RFC4918
sec 8.2.
* Fixed: TemporaryFileFilter now lets through GET's if they actually
exist on the backend. (r274)
* FIxed: Some methods didn't get passed through in the FilterTree (r283).
* Fixed: LockManager is now slightly more complex, Tree classes slightly
less. (r287)
0.6-alpha (2009-02-16)
* Added: Now uses streams for files, instead of strings.
This means it won't require to hold entire files in memory, which can be
an issue if you're dealing with big files. Note that this breaks
compatibility for put() and createFile methods.
* Added: HTTP Digest Authentication helper class.
* Added: Support for HTTP Range header
* Added: Support for ETags within If: headers
* Added: The API can now return ETags and override the default Content-Type
* Added: starting with basic framework for unittesting, using PHPUnit.
* Added: 49 unittests.
* Added: Abstraction for the HTTP request.
* Updated: Using Clark Notation for tags in properties. This means tags
are serialized as {namespace}tagName instead of namespace#tagName
* Fixed: HTTP_BasicAuth class now works as expected.
* Fixed: DAV_Server uses / for a default baseUrl.
* Fixed: Last modification date is no longer ignored in PROPFIND.
* Fixed: PROPFIND now sends back information about the requestUri even
when "Depth: 1" is specified.
0.5-alpha (2009-01-14)
* Added: Added a very simple example for implementing a mapping to PHP
file streams. This should allow easy implementation of for example a
WebDAV to FTP proxy.
* Added: HTTP Basic Authentication helper class.
* Added: Sabre_HTTP_Response class. This centralizes HTTP operations and
will be a start towards the creating of a testing framework.
* Updated: Backwards compatibility break: all require_once() statements
are removed
from all the files. It is now recommended to use autoloading of
classes, or just including lib/Sabre.includes.php. This fix was made
to allow easier integration into applications not using this standard
inclusion model.
* Updated: Better in-file documentation.
* Updated: Sabre_DAV_Tree can now work with Sabre_DAV_LockManager.
* Updated: Fixes a shared-lock bug.
* Updated: Removed ?> from the bottom of each php file.
* Updated: Split up some operations from Sabre_DAV_Server to
Sabre_HTTP_Response.
* Fixed: examples are now actually included in the pear package.
0.4-alpha (2008-11-05)
* Passes all litmus tests!
* Added: more examples
* Added: Custom property support
* Added: Shared lock support
* Added: Depth support to locks
* Added: Locking on unmapped urls (non-existent nodes)
* Fixed: Advertising as WebDAV class 3 support
0.3-alpha (2008-06-29)
* Fully working in MS Windows clients.
* Added: temporary file filter: support for smultron files.
* Added: Phing build scripts
* Added: PEAR package
* Fixed: MOVE bug identified using finder.
* Fixed: Using gzuncompress instead of gzdecode in the temporary file
filter. This seems more common.
0.2-alpha (2008-05-27)
* Somewhat working in Windows clients
* Added: Working PROPPATCH method (doesn't support custom properties yet)
* Added: Temporary filename handling system
* Added: Sabre_DAV_IQuota to return quota information
* Added: PROPFIND now reads the request body and only supplies the
requested properties
0.1-alpha (2008-04-04)
* First release!
* Passes litmus: basic, http and copymove test.
* Fully working in Finder and DavFSv2
Project started: 2007-12-13

28
dav/SabreDAV/LICENSE Normal file
View file

@ -0,0 +1,28 @@
Copyright (C) 2007-2012 Rooftop Solutions.
Copyright (C) 2007-2009 FileMobile inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the SabreDAV nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

42
dav/SabreDAV/README.md Normal file
View file

@ -0,0 +1,42 @@
# What is SabreDAV
SabreDAV allows you to easily add WebDAV support to a PHP application. SabreDAV is meant to cover the entire standard, and attempts to allow integration using an easy to understand API.
### Feature list:
* Fully WebDAV compliant
* Supports Windows XP, Windows Vista, Mac OS/X, DavFSv2, Cadaver, Netdrive, Open Office, and probably more.
* Passing all Litmus tests.
* Supporting class 1, 2 and 3 Webdav servers.
* Locking support.
* Custom property support.
* CalDAV (tested with [Evolution](http://code.google.com/p/sabredav/wiki/Evolution), [iCal](http://code.google.com/p/sabredav/wiki/ICal), [iPhone](http://code.google.com/p/sabredav/wiki/IPhone) and [Lightning](http://code.google.com/p/sabredav/wiki/Lightning)).
* CardDAV (tested with [OS/X addressbook](http://code.google.com/p/sabredav/wiki/OSXAddressbook), the [iOS addressbook](http://code.google.com/p/sabredav/wiki/iOSCardDAV) and [Evolution](http://code.google.com/p/sabredav/wiki/Evolution)).
* Over 97% unittest code coverage.
### Supported RFC's:
* [RFC2617](http://www.ietf.org/rfc/rfc2617.txt): Basic/Digest auth.
* [RFC2518](http://www.ietf.org/rfc/rfc2518.txt): First WebDAV spec.
* [RFC3744](http://www.ietf.org/rfc/rfc3744.txt): ACL (some features missing).
* [RFC4709](http://www.ietf.org/rfc/rfc4709.txt): [DavMount](http://code.google.com/p/sabredav/wiki/DavMount).
* [RFC4791](http://www.ietf.org/rfc/rfc4791.txt): CalDAV.
* [RFC4918](http://www.ietf.org/rfc/rfc4918.txt): WebDAV revision.
* [RFC5397](http://www.ietf.org/rfc/rfc5689.txt): current-user-principal.
* [RFC5689](http://www.ietf.org/rfc/rfc5689.txt): Extended MKCOL.
* [RFC5789](http://tools.ietf.org/html/rfc5789): PATCH method for HTTP.
* [RFC6352](http://www.ietf.org/rfc/rfc6352.txt): CardDAV
* [draft-daboo-carddav-directory-gateway](http://tools.ietf.org/html/draft-daboo-carddav-directory-gateway): CardDAV directory gateway
* CalDAV ctag, CalDAV-proxy.
## Live Demo
### Head over to:
* Url: [http://demo.sabredav.org/public/](http://demo.sabredav.org/public/)
* Username: testuser
* Password: test
**Please note:** Due to the webserver stack (nginx with varnish) some clients will not work correctly. At the very least this includes Finder and Cyberduck. Any client using chunked transfer encoding or expect *100-Continue* will fail.
The demo site is kindly hosted by sourceforge, so take it easy with the diskspace. It's limited!

View file

@ -0,0 +1,248 @@
#!/usr/bin/env python
#
# Copyright 2006, 2007 Google Inc. All Rights Reserved.
# Author: danderson@google.com (David Anderson)
#
# Script for uploading files to a Google Code project.
#
# This is intended to be both a useful script for people who want to
# streamline project uploads and a reference implementation for
# uploading files to Google Code projects.
#
# To upload a file to Google Code, you need to provide a path to the
# file on your local machine, a small summary of what the file is, a
# project name, and a valid account that is a member or owner of that
# project. You can optionally provide a list of labels that apply to
# the file. The file will be uploaded under the same name that it has
# in your local filesystem (that is, the "basename" or last path
# component). Run the script with '--help' to get the exact syntax
# and available options.
#
# Note that the upload script requests that you enter your
# googlecode.com password. This is NOT your Gmail account password!
# This is the password you use on googlecode.com for committing to
# Subversion and uploading files. You can find your password by going
# to http://code.google.com/hosting/settings when logged in with your
# Gmail account. If you have already committed to your project's
# Subversion repository, the script will automatically retrieve your
# credentials from there (unless disabled, see the output of '--help'
# for details).
#
# If you are looking at this script as a reference for implementing
# your own Google Code file uploader, then you should take a look at
# the upload() function, which is the meat of the uploader. You
# basically need to build a multipart/form-data POST request with the
# right fields and send it to https://PROJECT.googlecode.com/files .
# Authenticate the request using HTTP Basic authentication, as is
# shown below.
#
# Licensed under the terms of the Apache Software License 2.0:
# http://www.apache.org/licenses/LICENSE-2.0
#
# Questions, comments, feature requests and patches are most welcome.
# Please direct all of these to the Google Code users group:
# http://groups.google.com/group/google-code-hosting
"""Google Code file uploader script.
"""
__author__ = 'danderson@google.com (David Anderson)'
import httplib
import os.path
import optparse
import getpass
import base64
import sys
def upload(file, project_name, user_name, password, summary, labels=None):
"""Upload a file to a Google Code project's file server.
Args:
file: The local path to the file.
project_name: The name of your project on Google Code.
user_name: Your Google account name.
password: The googlecode.com password for your account.
Note that this is NOT your global Google Account password!
summary: A small description for the file.
labels: an optional list of label strings with which to tag the file.
Returns: a tuple:
http_status: 201 if the upload succeeded, something else if an
error occurred.
http_reason: The human-readable string associated with http_status
file_url: If the upload succeeded, the URL of the file on Google
Code, None otherwise.
"""
# The login is the user part of user@gmail.com. If the login provided
# is in the full user@domain form, strip it down.
if user_name.endswith('@gmail.com'):
user_name = user_name[:user_name.index('@gmail.com')]
form_fields = [('summary', summary)]
if labels is not None:
form_fields.extend([('label', l.strip()) for l in labels])
content_type, body = encode_upload_request(form_fields, file)
upload_host = '%s.googlecode.com' % project_name
upload_uri = '/files'
auth_token = base64.b64encode('%s:%s'% (user_name, password))
headers = {
'Authorization': 'Basic %s' % auth_token,
'User-Agent': 'Googlecode.com uploader v0.9.4',
'Content-Type': content_type,
}
server = httplib.HTTPSConnection(upload_host)
server.request('POST', upload_uri, body, headers)
resp = server.getresponse()
server.close()
if resp.status == 201:
location = resp.getheader('Location', None)
else:
location = None
return resp.status, resp.reason, location
def encode_upload_request(fields, file_path):
"""Encode the given fields and file into a multipart form body.
fields is a sequence of (name, value) pairs. file is the path of
the file to upload. The file will be uploaded to Google Code with
the same file name.
Returns: (content_type, body) ready for httplib.HTTP instance
"""
BOUNDARY = '----------Googlecode_boundary_reindeer_flotilla'
CRLF = '\r\n'
body = []
# Add the metadata about the upload first
for key, value in fields:
body.extend(
['--' + BOUNDARY,
'Content-Disposition: form-data; name="%s"' % key,
'',
value,
])
# Now add the file itself
file_name = os.path.basename(file_path)
f = open(file_path, 'rb')
file_content = f.read()
f.close()
body.extend(
['--' + BOUNDARY,
'Content-Disposition: form-data; name="filename"; filename="%s"'
% file_name,
# The upload server determines the mime-type, no need to set it.
'Content-Type: application/octet-stream',
'',
file_content,
])
# Finalize the form body
body.extend(['--' + BOUNDARY + '--', ''])
return 'multipart/form-data; boundary=%s' % BOUNDARY, CRLF.join(body)
def upload_find_auth(file_path, project_name, summary, labels=None,
user_name=None, password=None, tries=3):
"""Find credentials and upload a file to a Google Code project's file server.
file_path, project_name, summary, and labels are passed as-is to upload.
Args:
file_path: The local path to the file.
project_name: The name of your project on Google Code.
summary: A small description for the file.
labels: an optional list of label strings with which to tag the file.
config_dir: Path to Subversion configuration directory, 'none', or None.
user_name: Your Google account name.
tries: How many attempts to make.
"""
while tries > 0:
if user_name is None:
# Read username if not specified or loaded from svn config, or on
# subsequent tries.
sys.stdout.write('Please enter your googlecode.com username: ')
sys.stdout.flush()
user_name = sys.stdin.readline().rstrip()
if password is None:
# Read password if not loaded from svn config, or on subsequent tries.
print 'Please enter your googlecode.com password.'
print '** Note that this is NOT your Gmail account password! **'
print 'It is the password you use to access Subversion repositories,'
print 'and can be found here: http://code.google.com/hosting/settings'
password = getpass.getpass()
status, reason, url = upload(file_path, project_name, user_name, password,
summary, labels)
# Returns 403 Forbidden instead of 401 Unauthorized for bad
# credentials as of 2007-07-17.
if status in [httplib.FORBIDDEN, httplib.UNAUTHORIZED]:
# Rest for another try.
user_name = password = None
tries = tries - 1
else:
# We're done.
break
return status, reason, url
def main():
parser = optparse.OptionParser(usage='googlecode-upload.py -s SUMMARY '
'-p PROJECT [options] FILE')
parser.add_option('-s', '--summary', dest='summary',
help='Short description of the file')
parser.add_option('-p', '--project', dest='project',
help='Google Code project name')
parser.add_option('-u', '--user', dest='user',
help='Your Google Code username')
parser.add_option('-w', '--password', dest='password',
help='Your Google Code password')
parser.add_option('-l', '--labels', dest='labels',
help='An optional list of comma-separated labels to attach '
'to the file')
options, args = parser.parse_args()
if not options.summary:
parser.error('File summary is missing.')
elif not options.project:
parser.error('Project name is missing.')
elif len(args) < 1:
parser.error('File to upload not provided.')
elif len(args) > 1:
parser.error('Only one file may be specified.')
file_path = args[0]
if options.labels:
labels = options.labels.split(',')
else:
labels = None
status, reason, url = upload_find_auth(file_path, options.project,
options.summary, labels,
options.user, options.password)
if url:
print 'The file was uploaded successfully.'
print 'URL: %s' % url
return 0
else:
print 'An error occurred. Your file was not uploaded.'
print 'Google Code upload server said: %s (%s)' % (reason, status)
return 1
if __name__ == '__main__':
sys.exit(main())

378
dav/SabreDAV/bin/gwdg.php Normal file
View file

@ -0,0 +1,378 @@
#!/usr/bin/env php
<?php
/**
* Documentation generator
*
* This scripts scans all files in the lib/ directory, and generates
* Google Code wiki documentation.
*
* This script is rather crappy. It does what it needs to do, but uses global
* variables and it might be a hard to read.
*
* I'm not sure if I care though. Maybe one day this can become a separate
* project
*
* To run this script, just execute on the command line. The script assumes
* it's in the standard bin/ directory.
*/
date_default_timezone_set('UTC');
$libDir = realpath(__DIR__ . '/../lib');
$outputDir = __DIR__ . '/../docs/wikidocs';
if (!is_dir($outputDir)) mkdir($outputDir);
$files = new RecursiveDirectoryIterator($libDir);
$files = new RecursiveIteratorIterator($files, RecursiveIteratorIterator::LEAVES_ONLY);
include_once $libDir . '/Sabre/autoload.php';
// Finding all classnames
$classNames = findClassNames($files);
echo "Found: " . count($classNames) . " classes and interfaces\n";
echo "Generating class tree\n";
$classTree = getClassTree($classNames);
$packageList = array();
foreach($classNames as $className) {
echo "Creating docs for: " . $className . "\n";
$output = createDoc($className,isset($classTree[$className])?$classTree[$className]:array());
file_put_contents($outputDir . '/' . $className . '.wiki', $output);
}
echo "Creating indexes\n";
$output = createSidebarIndex($packageList);
file_put_contents($outputDir . '/APIIndex.wiki', $output);
function findClassNames($files) {
$classNames = array();
foreach($files as $fileName=>$fileInfo) {
$tokens = token_get_all(file_get_contents($fileName));
foreach($tokens as $tokenIndex=>$token) {
if ($token[0]===T_CLASS || $token[0]===T_INTERFACE) {
$classNames[] = $tokens[$tokenIndex+2][1];
}
}
}
return $classNames;
}
function getClassTree($classNames) {
$classTree = array();
foreach($classNames as $className) {
if (!class_exists($className) && !interface_exists($className)) continue;
$rClass = new ReflectionClass($className);
$parent = $rClass->getParentClass();
if ($parent) $parent = $parent->name;
if (!isset($classTree[$parent])) $classTree[$parent] = array();
$classTree[$parent][] = $className;
foreach($rClass->getInterfaceNames() as $interface) {
if (!isset($classTree[$interface])) {
$classTree[$interface] = array();
}
$classTree[$interface][] = $className;
}
}
return $classTree;
}
function createDoc($className, $extendedBy) {
// ew
global $packageList;
ob_start();
$rClass = new ReflectionClass($className);
echo "#summary API documentation for: ", $rClass->getName() , "\n";
echo "#labels APIDoc\n";
echo "#sidebar APIIndex\n";
echo "=`" . $rClass->getName() . "`=\n";
echo "\n";
$docs = parseDocs($rClass->getDocComment());
echo $docs['description'] . "\n";
echo "\n";
$parentClass = $rClass->getParentClass();
if($parentClass) {
echo " * Parent class: [" . $parentClass->getName() . "]\n";
}
if ($interfaces = $rClass->getInterfaceNames()) {
$interfaces = array_map(function($int) { return '[' . $int . ']'; },$interfaces);
echo " * Implements: " . implode(", ", $interfaces) . "\n";
}
$classType = $rClass->isInterface()?'interface':'class';
if (isset($docs['deprecated'])) {
echo " * *Warning: This $classType is deprecated, and should not longer be used.*\n";
}
if ($rClass->isInterface()) {
echo " * This is an interface.\n";
} elseif ($rClass->isAbstract()) {
echo " * This is an abstract class.\n";
}
if (isset($docs['package'])) {
$package = $docs['package'];
if (isset($docs['subpackage'])) {
$package.='_' . $docs['subpackage'];
}
if (!isset($packageList[$package])) {
$packageList[$package] = array();
}
$packageList[$package][] = $rClass->getName();
}
if ($extendedBy) {
echo "\n";
if ($classType==='interface') {
echo "This interface is extended by the following interfaces:\n";
foreach($extendedBy as $className) {
if (interface_exists($className)) {
echo " * [" . $className . "]\n";
}
}
echo "\n";
echo "This interface is implemented by the following classes:\n";
} else {
echo "This class is extended by the following classes:\n";
}
foreach($extendedBy as $className) {
if (class_exists($className)) {
echo " * [" . $className . "]\n";
}
}
echo "\n";
}
echo "\n";
echo "==Properties==\n";
echo "\n";
$properties = $rClass->getProperties(ReflectionProperty::IS_STATIC | ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED);
if (count($properties)>0) {
foreach($properties as $rProperty) {
createPropertyDoc($rProperty);
}
} else {
echo "This $classType does not define any public or protected properties.\n";
}
echo "\n";
echo "==Methods==\n";
echo "\n";
$methods = $rClass->getMethods(ReflectionMethod::IS_PUBLIC | ReflectionMethod::IS_PROTECTED);
if (count($methods)>0) {
foreach($methods as $rMethod) {
createMethodDoc($rMethod, $rClass);
}
} else {
echo "\nThis $classType does not define any public or protected methods.\n";
}
return ob_get_clean();
}
function createMethodDoc($rMethod, $rClass) {
echo "===`" . $rMethod->getName() . "`===\n";
echo "\n";
$docs = parseDocs($rMethod->getDocComment());
$return = isset($docs['return'])?$docs['return']:'void';
echo "{{{\n";
echo $return . " " . $rMethod->class . "::" . $rMethod->getName() . "(";
foreach($rMethod->getParameters() as $parameter) {
if ($parameter->getPosition()>0) echo ", ";
if ($class = $parameter->getClass()) {
echo $class->name . " ";
} elseif (isset($docs['param'][$parameter->name])) {
echo $docs['param'][$parameter->name] . " ";
}
echo '$' . $parameter->name;
if ($parameter->isOptional() && $parameter->isDefaultValueAvailable()) {
$default = $parameter->getDefaultValue();
$default = var_export($default,true);
$default = str_replace("\n","",$default);
echo " = " . $default;
}
}
echo ")\n";
echo "}}}\n";
echo "\n";
echo $docs['description'] . "\n";
echo "\n";
$hasProp = false;
if (isset($docs['deprecated'])) {
echo " * *Warning: This method is deprecated, and should not longer be used.*\n";
$hasProp = true;
}
if ($rMethod->isProtected()) {
echo " * This method is protected.\n";
$hasProp = true;
}
if ($rMethod->isPrivate()) {
echo " * This method is private.\n";
$hasProp = true;
}
if ($rMethod->isAbstract()) {
echo " * This is an abstract method\n";
$hasProp = true;
}
if ($rMethod->class != $rClass->name) {
echo " * Defined in [" . $rMethod->class . "]\n";
$hasProp = true;
}
if ($hasProp) echo "\n";
}
function createPropertyDoc($rProperty) {
echo "===`" . $rProperty->getName() . "`===\n";
echo "\n";
$docs = parseDocs($rProperty->getDocComment());
$visibility = 'public';
if ($rProperty->isProtected()) $visibility = 'protected';
if ($rProperty->isPrivate()) $visibility = 'private';
echo "{{{\n";
echo $visibility . " " . $rProperty->class . "::$" . $rProperty->getName();
echo "\n}}}\n";
echo "\n";
echo $docs['description'] . "\n";
echo "\n";
$hasProp = false;
if (isset($docs['deprecated'])) {
echo " * *Warning: This property is deprecated, and should not longer be used.*\n";
$hasProp = true;
}
if ($rProperty->isProtected()) {
echo " * This property is protected.\n";
$hasProp = true;
}
if ($rProperty->isPrivate()) {
echo " * This property is private.\n";
$hasProp = true;
}
if ($rProperty->isStatic()) {
echo " * This property is static.\n";
$hasProp = true;
}
if ($hasProp) echo "\n";
}
function parseDocs($docString) {
$params = array();
$description = array();
// Trimming all the comment characters
$docString = trim($docString,"\n*/ ");
$docString = explode("\n",$docString);
foreach($docString as $str) {
$str = ltrim($str,'* ');
$str = trim($str);
if ($str && $str[0]==='@') {
$r = explode(' ',substr($str,1),2);
$paramName = $r[0];
$paramValue = (count($r)>1)?$r[1]:'';
// 'param' paramName is special. Confusing, I know.
if ($paramName==='param') {
if (!isset($params['param'])) $params['param'] = array();
$paramValue = explode(' ', $paramValue,3);
$params['param'][substr($paramValue[1],1)] = $paramValue[0];
} else {
$params[$paramName] = trim($paramValue);
}
} else {
$description[]=$str;
}
}
$params['description'] = trim(implode("\n",$description),"\n ");
return $params;
}
function createSidebarIndex($packageList) {
ob_start();
echo "#labels APIDocs\n";
echo "#summary List of all classes, neatly organized\n";
echo "=API Index=\n";
foreach($packageList as $package=>$classes) {
echo " * $package\n";
sort($classes);
foreach($classes as $class) {
echo " * [$class $class]\n";
}
}
return ob_get_clean();
}

View file

@ -0,0 +1,250 @@
<?php
echo "SabreDAV migrate script for version 1.7\n";
if ($argc<2) {
echo <<<HELLO
This script help you migrate from a pre-1.7 database to 1.7 and later\n
It is important to note, that this script only touches the 'calendarobjects'
table.
If you do not have this table, or don't use the default PDO CalDAV backend
it's pointless to run this script.
Keep in mind that some processing will be done on every single record of this
table and in addition, ALTER TABLE commands will be executed.
If you have a large calendarobjects table, this may mean that this process
takes a while.
Usage:
{$argv[0]} [pdo-dsn] [username] [password]
For example:
{$argv[0]} mysql:host=localhost;dbname=sabredav root password
{$argv[0]} sqlite:data/sabredav.db
HELLO;
exit();
}
if (file_exists(__DIR__ . '/../lib/Sabre/VObject/includes.php')) {
include __DIR__ . '/../lib/Sabre/VObject/includes.php';
} else {
// If, for some reason VObject was not found in the vicinity,
// we'll try to grab it from the default path.
require 'Sabre/VObject/includes.php';
}
$dsn = $argv[1];
$user = isset($argv[2])?$argv[2]:null;
$pass = isset($argv[3])?$argv[3]:null;
echo "Connecting to database: " . $dsn . "\n";
$pdo = new PDO($dsn, $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
echo "Validating existing table layout\n";
// The only cross-db way to do this, is to just fetch a single record.
$row = $pdo->query("SELECT * FROM calendarobjects LIMIT 1")->fetch();
if (!$row) {
echo "Error: This database did not have any records in the calendarobjects table, you should just recreate the table.\n";
exit(-1);
}
$requiredFields = array(
'id',
'calendardata',
'uri',
'calendarid',
'lastmodified',
);
foreach($requiredFields as $requiredField) {
if (!array_key_exists($requiredField,$row)) {
echo "Error: The current 'calendarobjects' table was missing a field we expected to exist.\n";
echo "For safety reasons, this process is stopped.\n";
exit(-1);
}
}
$fields17 = array(
'etag',
'size',
'componenttype',
'firstoccurence',
'lastoccurence',
);
$found = 0;
foreach($fields17 as $field) {
if (array_key_exists($field, $row)) {
$found++;
}
}
if ($found === 0) {
echo "The database had the 1.6 schema. Table will now be altered.\n";
echo "This may take some time for large tables\n";
switch($pdo->getAttribute(PDO::ATTR_DRIVER_NAME)) {
case 'mysql' :
$pdo->exec(<<<SQL
ALTER TABLE calendarobjects
ADD etag VARCHAR(32),
ADD size INT(11) UNSIGNED,
ADD componenttype VARCHAR(8),
ADD firstoccurence INT(11) UNSIGNED,
ADD lastoccurence INT(11) UNSIGNED
SQL
);
break;
case 'sqlite' :
$pdo->exec('ALTER TABLE calendarobjects ADD etag text');
$pdo->exec('ALTER TABLE calendarobjects ADD size integer');
$pdo->exec('ALTER TABLE calendarobjects ADD componenttype TEXT');
$pdo->exec('ALTER TABLE calendarobjects ADD firstoccurence integer');
$pdo->exec('ALTER TABLE calendarobjects ADD lastoccurence integer');
break;
default :
die('This upgrade script does not support this driver (' . $pdo->getAttribute(PDO::ATTR_DRIVER_NAME) . ")\n");
}
echo "Database schema upgraded.\n";
} elseif ($found === 5) {
echo "Database already had the 1.7 schema\n";
} else {
echo "The database had $found out of 5 from the changes for 1.7. This is scary and unusual, so we have to abort.\n";
echo "You can manually try to upgrade the schema, and then run this script again.\n";
exit(-1);
}
echo "Now, we need to parse every record and pull out some information.\n";
$result = $pdo->query('SELECT id, calendardata FROM calendarobjects');
$stmt = $pdo->prepare('UPDATE calendarobjects SET etag = ?, size = ?, componenttype = ?, firstoccurence = ?, lastoccurence = ? WHERE id = ?');
echo "Total records found: " . $result->rowCount() . "\n";
$done = 0;
$total = $result->rowCount();
while($row = $result->fetch()) {
try {
$newData = getDenormalizedData($row['calendardata']);
} catch (Exception $e) {
echo "===\nException caught will trying to parser calendarobject.\n";
echo "Error message: " . $e->getMessage() . "\n";
echo "Record id: " . $row['id'] . "\n";
echo "This record is ignored, you should inspect it to see if there's anything wrong.\n===\n";
continue;
}
$stmt->execute(array(
$newData['etag'],
$newData['size'],
$newData['componentType'],
$newData['firstOccurence'],
$newData['lastOccurence'],
$row['id'],
));
$done++;
if ($done % 500 === 0) {
echo "Completed: $done / $total\n";
}
}
echo "Process completed!\n";
/**
* Parses some information from calendar objects, used for optimized
* calendar-queries.
*
* Blantently copied from Sabre_CalDAV_Backend_PDO
*
* Returns an array with the following keys:
* * etag
* * size
* * componentType
* * firstOccurence
* * lastOccurence
*
* @param string $calendarData
* @return array
*/
function getDenormalizedData($calendarData) {
$vObject = Sabre_VObject_Reader::read($calendarData);
$componentType = null;
$component = null;
$firstOccurence = null;
$lastOccurence = null;
foreach($vObject->getComponents() as $component) {
if ($component->name!=='VTIMEZONE') {
$componentType = $component->name;
break;
}
}
if (!$componentType) {
throw new Sabre_DAV_Exception_BadRequest('Calendar objects must have a VJOURNAL, VEVENT or VTODO component');
}
if ($componentType === 'VEVENT') {
$firstOccurence = $component->DTSTART->getDateTime()->getTimeStamp();
// Finding the last occurence is a bit harder
if (!isset($component->RRULE)) {
if (isset($component->DTEND)) {
$lastOccurence = $component->DTEND->getDateTime()->getTimeStamp();
} elseif (isset($component->DURATION)) {
$endDate = clone $component->DTSTART->getDateTime();
$endDate->add(Sabre_VObject_DateTimeParser::parse($component->DURATION->value));
$lastOccurence = $endDate->getTimeStamp();
} elseif ($component->DTSTART->getDateType()===Sabre_VObject_Property_DateTime::DATE) {
$endDate = clone $component->DTSTART->getDateTime();
$endDate->modify('+1 day');
$lastOccurence = $endDate->getTimeStamp();
} else {
$lastOccurence = $firstOccurence;
}
} else {
$it = new Sabre_VObject_RecurrenceIterator($vObject, (string)$component->UID);
$maxDate = new DateTime(Sabre_CalDAV_Backend_PDO::MAX_DATE);
if ($it->isInfinite()) {
$lastOccurence = $maxDate->getTimeStamp();
} else {
$end = $it->getDtEnd();
while($it->valid() && $end < $maxDate) {
$end = $it->getDtEnd();
$it->next();
}
$lastOccurence = $end->getTimeStamp();
}
}
}
return array(
'etag' => md5($calendarData),
'size' => strlen($calendarData),
'componentType' => $componentType,
'firstOccurence' => $firstOccurence,
'lastOccurence' => $lastOccurence,
);
}

View file

@ -0,0 +1,140 @@
#!/usr/bin/env python
#
# Copyright (c) 2009-2010 Evert Pot
# All rights reserved.
# http://www.rooftopsolutions.nl/
#
# This utility is distributed along with SabreDAV
# license: http://code.google.com/p/sabredav/wiki/License Modified BSD License
import os
from optparse import OptionParser
import time
def getfreespace(path):
stat = os.statvfs(path)
return stat.f_frsize * stat.f_bavail
def getbytesleft(path,treshold):
return getfreespace(path)-treshold
def run(cacheDir, treshold, sleep=5, simulate=False, min_erase = 0):
bytes = getbytesleft(cacheDir,treshold)
if (bytes>0):
print "Bytes to go before we hit treshhold:", bytes
else:
print "Treshold exceeded with:", -bytes, "bytes"
dir = os.listdir(cacheDir)
dir2 = []
for file in dir:
path = cacheDir + '/' + file
dir2.append({
"path" : path,
"atime": os.stat(path).st_atime,
"size" : os.stat(path).st_size
})
dir2.sort(lambda x,y: int(x["atime"]-y["atime"]))
filesunlinked = 0
gainedspace = 0
# Left is the amount of bytes that need to be freed up
# The default is the 'min_erase setting'
left = min_erase
# If the min_erase setting is lower than the amount of bytes over
# the treshold, we use that number instead.
if left < -bytes :
left = -bytes
print "Need to delete at least:", left;
for file in dir2:
# Only deleting files if we're not simulating
if not simulate: os.unlink(file["path"])
left = int(left - file["size"])
gainedspace = gainedspace + file["size"]
filesunlinked = filesunlinked + 1
if(left<0):
break
print "%d files deleted (%d bytes)" % (filesunlinked, gainedspace)
time.sleep(sleep)
def main():
parser = OptionParser(
version="naturalselecton v0.3",
description="Cache directory manager. Deletes cache entries based on accesstime and free space tresholds.\n" +
"This utility is distributed alongside SabreDAV.",
usage="usage: %prog [options] cacheDirectory",
)
parser.add_option(
'-s',
dest="simulate",
action="store_true",
help="Don't actually make changes, but just simulate the behaviour",
)
parser.add_option(
'-r','--runs',
help="How many times to check before exiting. -1 is infinite, which is the default",
type="int",
dest="runs",
default=-1
)
parser.add_option(
'-n','--interval',
help="Sleep time in seconds (default = 5)",
type="int",
dest="sleep",
default=5
)
parser.add_option(
'-l','--treshold',
help="Treshhold in bytes (default = 10737418240, which is 10GB)",
type="int",
dest="treshold",
default=10737418240
)
parser.add_option(
'-m', '--min-erase',
help="Minimum number of bytes to erase when the treshold is reached. " +
"Setting this option higher will reduce the amount of times the cache directory will need to be scanned. " +
"(the default is 1073741824, which is 1GB.)",
type="int",
dest="min_erase",
default=1073741824
)
options,args = parser.parse_args()
if len(args)<1:
parser.error("This utility requires at least 1 argument")
cacheDir = args[0]
print "Natural Selection"
print "Cache directory:", cacheDir
free = getfreespace(cacheDir);
print "Current free disk space:", free
runs = options.runs;
while runs!=0 :
run(
cacheDir,
sleep=options.sleep,
simulate=options.simulate,
treshold=options.treshold,
min_erase=options.min_erase
)
if runs>0:
runs = runs - 1
if __name__ == '__main__' :
main()

View file

@ -0,0 +1,321 @@
#!/usr/bin/env php
<?php
date_default_timezone_set('UTC');
$make = false;
$packageName = null;
foreach($argv as $index=>$arg) {
if ($index==0) continue;
if ($arg=='make') {
$make = true;
continue;
}
$packageName = $arg;
}
if (is_null($packageName)) {
echo "A packagename is required\n";
die(1);
}
if (!is_dir('build/' . $packageName)) {
echo "Could not find package directory: build/$packageName\n";
die(2);
}
// We'll figure out something better for this one day
$dependencies = array(
array(
'type' => 'php',
'min' => '5.3.1',
),
array(
'type' => 'pearinstaller',
'min' => '1.9',
),
);
switch($packageName) {
case 'Sabre' :
$summary = 'Sabretooth base package.';
$description = <<<TEXT
The base package provides some functionality used by all packages.
Currently this is only an autoloader
TEXT;
$version = '1.0.0';
$stability = 'stable';
break;
case 'Sabre_DAV' :
$summary = 'Sabre_DAV is a WebDAV framework for PHP.';
$description = <<<TEXT
SabreDAV allows you to easily integrate WebDAV access into your existing PHP application.
Feature List:
* Fully WebDAV (class 1, 2, 3) compliant
* Supports Windows clients, OS/X, DavFS, Cadaver, and pretty much everything we've come accross
* Custom property support
* RFC4918-compliant
* Authentication support
* Plugin system
TEXT;
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre',
'channel' => 'pear.sabredav.org',
'min' => '1.0.0',
);
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre_HTTP',
'channel' => 'pear.sabredav.org',
'min' => '1.6.0',
);
break;
case 'Sabre_HTTP' :
$summary = 'Sabre_HTTP provides various HTTP helpers, for input and output and authentication';
$description = <<<TEXT
Sabre_HTTP effectively wraps around \$_SERVER, php://input, php://output and the headers method,
allowing for a central interface to deal with this as well as easier unittesting.
In addition Sabre_HTTP provides classes for Basic, Digest and Amazon AWS authentication.
TEXT;
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre',
'channel' => 'pear.sabredav.org',
'min' => '1.0.0',
);
break;
case 'Sabre_DAVACL' :
$summary = 'Sabre_DAVACL provides rfc3744 support.';
$description = <<<TEXT
Sabre_DAVACL is the RFC3744 implementation for SabreDAV. It provides principals
(users and groups) and access control.
TEXT;
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre',
'channel' => 'pear.sabredav.org',
'min' => '1.0.0',
);
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre_DAV',
'channel' => 'pear.sabredav.org',
'min' => '1.6.0',
);
break;
case 'Sabre_CalDAV' :
$summary = 'Sabre_CalDAV provides CalDAV extensions to SabreDAV';
$description = <<<TEXT
Sabre_CalDAV provides RFC4791 (CalDAV) support to Sabre_DAV.
Feature list:
* Multi-user Calendar Server
* Support for Apple iCal, Evolution, Sunbird, Lightning
TEXT;
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre',
'channel' => 'pear.sabredav.org',
'min' => '1.0.0',
);
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre_HTTP',
'channel' => 'pear.sabredav.org',
'min' => '1.6.0',
);
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre_DAV',
'channel' => 'pear.sabredav.org',
'min' => '1.6.0',
);
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre_DAVACL',
'channel' => 'pear.sabredav.org',
'min' => '1.6.0',
);
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre_VObject',
'channel' => 'pear.sabredav.org',
'min' => '1.3.0',
);
break;
case 'Sabre_CardDAV' :
$summary = 'Sabre_CardDAV provides CardDAV extensions to SabreDAV';
$description = <<<TEXT
Sabre_CardDAV provides CardDAV support to Sabre_DAV.
Feature list:
* Multi-user addressbook server
* ACL support
* Support for OS/X, iOS, Evolution and probably more
* Hook-ins for creating a global \'directory\'.
TEXT;
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre',
'channel' => 'pear.sabredav.org',
'min' => '1.0.0',
);
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre_HTTP',
'channel' => 'pear.sabredav.org',
'min' => '1.6.0',
);
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre_DAV',
'channel' => 'pear.sabredav.org',
'min' => '1.6.0',
);
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre_DAVACL',
'channel' => 'pear.sabredav.org',
'min' => '1.6.0',
);
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre_VObject',
'channel' => 'pear.sabredav.org',
'min' => '1.3.0',
);
break;
case 'Sabre_VObject' :
$summary = 'Sabre_VObject is a natural-interface iCalendar and vCard reader';
$description = <<<TEXT
Sabre_VObject is an intuitive reader for iCalendar and vCard objects.
It provides a natural array/object accessor interface to the parsed tree, much like
simplexml for XML files.
TEXT;
$dependencies[] = array(
'type' => 'package',
'name' => 'Sabre',
'channel' => 'pear.sabredav.org',
'min' => '1.0.0',
);
break;
}
if (!isset($version)) {
include 'lib/' . str_replace('_','/',$packageName) . '/Version.php';
$versionClassName = $packageName . '_Version';
$version = $versionClassName::VERSION;
$stability = $versionClassName::STABILITY;
}
$lead = 'Evert Pot';
$lead_email = 'evert@rooftopsolutions.nl';
$date = date('Y-m-d');
$license = 'Modified BSD';
$licenseuri = 'http://code.google.com/p/sabredav/wiki/License';
$notes = 'New release. Read the ChangeLog and announcement for more details';
$channel = 'pear.sabredav.org';
/* This function is intended to generate the full file list */
function parsePath($fullPath, $role, $padding = 4) {
$fileList = '';
$file = basename($fullPath);
if (is_dir($fullPath)) {
$fileList .= str_repeat(' ', $padding) . "<dir name=\"{$file}\">\n";
foreach(scandir($fullPath) as $subPath) {;
if ($subPath==='.' || $subPath==='..') continue;
$fileList .= parsePath($fullPath. '/' . $subPath,$role, $padding+2);
}
$fileList .= str_repeat(' ', $padding) . "</dir><!-- {$file} -->\n";
} elseif (is_file($fullPath)) {
$fileList .= str_repeat(' ', $padding) . "<file name=\"{$file}\" role=\"{$role}\" />\n";
}
return $fileList;
}
$rootDir = realpath('build/' . $packageName);
$fileList = parsePath($rootDir . '/Sabre', 'php');
$fileList .= parsePath($rootDir . '/examples', 'doc');
$fileList .= parsePath($rootDir . '/ChangeLog', 'doc');
$fileList .= parsePath($rootDir . '/LICENSE', 'doc');
$dependenciesXML = "\n";
foreach($dependencies as $dep) {
$pad = 8;
$dependenciesXML.=str_repeat(' ',$pad) . '<' . $dep['type'] . ">\n";
foreach($dep as $key=>$value) {
if ($key=='type') continue;
$dependenciesXML.=str_repeat(' ',$pad+2) . "<$key>$value</$key>\n";
}
$dependenciesXML.=str_repeat(' ',$pad) . '</' . $dep['type'] . ">\n";
}
$package = <<<XML
<?xml version="1.0"?>
<package version="2.0"
xmlns="http://pear.php.net/dtd/package-2.0">
<name>{$packageName}</name>
<channel>{$channel}</channel>
<summary>{$summary}</summary>
<description>{$description}</description>
<lead>
<name>{$lead}</name>
<user>{$lead}</user>
<email>{$lead_email}</email>
<active>true</active>
</lead>
<date>{$date}</date>
<version>
<release>{$version}</release>
<api>{$version}</api>
</version>
<stability>
<release>{$stability}</release>
<api>{$stability}</api>
</stability>
<license uri="{$licenseuri}">{$license}</license>
<notes>{$notes}</notes>
<contents>
<dir name="/">{$fileList}
</dir>
</contents>
<dependencies>
<required>{$dependenciesXML}
</required>
</dependencies>
<phprelease />
</package>
XML;
if (isset($argv) && in_array('make',$argv)) {
file_put_contents($rootDir . '/package.xml',$package);
} else {
echo $package;
}

268
dav/SabreDAV/build.xml Normal file
View file

@ -0,0 +1,268 @@
<?xml version="1.0"?>
<project name="SabreDAV" default="build" basedir=".">
<!-- Any default properties -->
<property file="build.properties" />
<!-- Where to write api documentation -->
<property name="sabredav.apidocspath" value="docs/api" />
<target name="build" depends="init, test, clean">
<mkdir dir="build" />
<echo msg="Building Sabre pear package" />
<mkdir dir="build/Sabre" />
<copy todir="build/Sabre">
<fileset dir="lib">
<include name="Sabre/autoload.php" />
</fileset>
</copy>
<copy todir="build/Sabre">
<fileset dir=".">
<include name="LICENSE" />
</fileset>
</copy>
<exec command="bin/pearpackage3.php make Sabre" checkreturn="true" />
<exec command="pear package" dir="build/Sabre" checkreturn="true" />
<echo msg="Building Sabre_HTTP pear package" />
<mkdir dir="build/Sabre_HTTP" />
<mkdir dir="build/Sabre_HTTP/Sabre" />
<copy todir="build/Sabre_HTTP" includeemptydirs="true" >
<fileset dir="lib">
<include name="Sabre/HTTP/**" />
</fileset>
</copy>
<copy todir="build/Sabre_HTTP">
<fileset dir=".">
<include name="LICENSE" />
<include name="ChangeLog" />
<include name="examples/basicauth.php" />
<include name="examples/digestauth.php" />
</fileset>
</copy>
<exec command="bin/pearpackage3.php make Sabre_HTTP" checkreturn="true" />
<exec command="pear package" dir="build/Sabre_HTTP" checkreturn="true" />
<echo msg="Building Sabre_DAV pear package" />
<mkdir dir="build/Sabre_DAV" />
<mkdir dir="build/Sabre_DAV/Sabre" />
<copy todir="build/Sabre_DAV" includeemptydirs="true" >
<fileset dir="lib">
<include name="Sabre/DAV/**" />
<exclude name="Sabre/DAVACL/**" />
<include name="Sabre.includes.php" />
</fileset>
</copy>
<copy todir="build/Sabre_DAV" includeemptydirs="true">
<fileset dir="." >
<include name="LICENSE" />
<include name="ChangeLog" />
<include name="examples/fileserver.php" />
<include name="examples/simplefsserver.php" />
<include name="examples/sql/*.locks.sql" />
<include name="examples/sql/*.users.sql" />
<include name="examples/webserver/*.conf" />
</fileset>
</copy>
<exec command="bin/pearpackage3.php make Sabre_DAV" checkreturn="true" />
<exec command="pear package" dir="build/Sabre_DAV" checkreturn="true" />
<!-- DAVACL -->
<echo msg="Building Sabre_DAVACL pear package" />
<mkdir dir="build/Sabre_DAVACL" />
<mkdir dir="build/Sabre_DAVACL/Sabre" />
<copy todir="build/Sabre_DAVACL" includeemptydirs="true" >
<fileset dir="lib">
<include name="Sabre/DAVACL/**" />
</fileset>
</copy>
<mkdir dir="build/Sabre_DAVACL" />
<copy todir="build/Sabre_DAVACL">
<fileset dir=".">
<include name="LICENSE" />
<include name="ChangeLog" />
<include name="examples/sql/*.principals.sql" />
</fileset>
</copy>
<exec command="bin/pearpackage3.php make Sabre_DAVACL" checkreturn="true" />
<exec command="pear package" dir="build/Sabre_DAVACL" checkreturn="true" />
<!-- CalDAV -->
<echo msg="Building Sabre_CalDAV pear package" />
<mkdir dir="build/Sabre_CalDAV" />
<mkdir dir="build/Sabre_CalDAV/Sabre" />
<copy todir="build/Sabre_CalDAV" includeemptydirs="true" >
<fileset dir="lib">
<include name="Sabre/CalDAV/**" />
</fileset>
</copy>
<mkdir dir="build/Sabre_CalDAV" />
<copy todir="build/Sabre_CalDAV">
<fileset dir=".">
<include name="LICENSE" />
<include name="ChangeLog" />
<include name="examples/calendarserver.php" />
<include name="examples/sql/*.calendars.sql" />
</fileset>
</copy>
<exec command="bin/pearpackage3.php make Sabre_CalDAV" checkreturn="true" />
<exec command="pear package" dir="build/Sabre_CalDAV" checkreturn="true" />
<!-- CardDAV -->
<echo msg="Building Sabre_CardDAV pear package" />
<mkdir dir="build/Sabre_CardDAV" />
<mkdir dir="build/Sabre_CardDAV/Sabre" />
<copy todir="build/Sabre_CardDAV" includeemptydirs="true" >
<fileset dir="lib">
<include name="Sabre/CardDAV/**" />
</fileset>
</copy>
<mkdir dir="build/Sabre_CardDAV" />
<copy todir="build/Sabre_CardDAV">
<fileset dir=".">
<include name="LICENSE" />
<include name="ChangeLog" />
<include name="examples/addressbookserver.php" />
<include name="examples/sql/*.addressbooks.sql" />
</fileset>
</copy>
<exec command="bin/pearpackage3.php make Sabre_CardDAV" checkreturn="true" />
<exec command="pear package" dir="build/Sabre_CardDAV" checkreturn="true" />
<!-- VObject -->
<echo msg="Building Sabre_VObject pear package" />
<mkdir dir="build/Sabre_VObject" />
<mkdir dir="build/Sabre_VObject/Sabre" />
<copy todir="build/Sabre_VObject" includeemptydirs="true" >
<fileset dir="lib">
<include name="Sabre/VObject/**" />
</fileset>
</copy>
<mkdir dir="build/Sabre_VObject" />
<copy todir="build/Sabre_VObject">
<fileset dir=".">
<include name="LICENSE" />
<include name="ChangeLog" />
</fileset>
</copy>
<exec command="bin/pearpackage3.php make Sabre_VObject" checkreturn="true" />
<exec command="pear package" dir="build/Sabre_VObject" checkreturn="true" />
<!-- moving tgz files -->
<move todir="build">
<mapper type="flatten" />
<fileset dir="build/">
<include name="**/*.tgz" />
</fileset>
</move>
<echo>Creating combined SabreDAV build</echo>
<mkdir dir="build/SabreDAV" />
<mkdir dir="build/SabreDAV/lib" />
<mkdir dir="build/SabreDAV/lib/Sabre" />
<mkdir dir="build/SabreDAV/lib/Sabre/CalDAV" />
<mkdir dir="build/SabreDAV/lib/Sabre/DAV" />
<mkdir dir="build/SabreDAV/lib/Sabre/DAV/Auth" />
<mkdir dir="build/SabreDAV/lib/Sabre/DAV/Locks" />
<mkdir dir="build/SabreDAV/lib/Sabre/HTTP" />
<mkdir dir="build/SabreDAV/lib/Sabre/VObject" />
<mkdir dir="build/SabreDAV/tests" />
<mkdir dir="build/SabreDAV/tests/Sabre" />
<mkdir dir="build/SabreDAV/tests/Sabre/CalDAV" />
<mkdir dir="build/SabreDAV/tests/Sabre/DAV" />
<mkdir dir="build/SabreDAV/tests/Sabre/HTTP" />
<mkdir dir="build/SabreDAV/tests/Sabre/DAV/Auth" />
<mkdir dir="build/SabreDAV/tests/Sabre/DAV/Locks" />
<mkdir dir="build/SabreDAV/tests/Sabre/VObject" />
<copy todir="build/SabreDAV" includeemptydirs="true">
<fileset dir=".">
<include name="lib/**/*.php" />
<include name="lib/Sabre/DAV/Browser/assets/**" />
<include name="ChangeLog" />
<include name="LICENSE" />
<include name="examples/**.php" />
<include name="examples/**/*.sql" />
<include name="bin/naturalselection.py" />
<include name="bin/migrateto17.php" />
<include name="tests/**/*.xml" />
<include name="tests/**/*.php" />
</fileset>
</copy>
<mkdir dir="build/SabreDAV/tests/temp" />
<zip destfile="build/SabreDAV-${sabredav.version}.zip" basedir="build/SabreDAV" prefix="SabreDAV/" />
</target>
<target name="clean" depends="init">
<echo msg="Removing build files (cleaning up distribution)" />
<delete dir="docs/api" />
<delete dir="build" />
</target>
<target name="release" depends="init,clean,test,build">
<echo>Creating Git release tag</echo>
<exec command="git tag ${sabredav.version}" checkreturn="false" passthru="1" />
<echo>Uploading to Google Code</echo>
<propertyprompt propertyName="googlecode.username" promptText="Enter your googlecode username" useExistingValue="true" />
<propertyprompt propertyName="googlecode.password" promptText="Enter your googlecode password" useExistingValue="true" />
<exec command="bin/googlecode_upload.py -s 'SabreDAV ${sabredav.version}' -p sabredav --labels=${sabredav.ucstability} -u '${googlecode.username}' -w '${googlecode.password}' build/SabreDAV-${sabredav.version}.zip" checkreturn="true" />
</target>
<target name="test">
<phpunit haltonfailure="1" haltonerror="1" bootstrap="tests/bootstrap.php" haltonskipped="1" printsummary="1">
<batchtest>
<fileset dir="tests">
<include name="**/*.php"/>
</fileset>
</batchtest>
</phpunit>
</target>
<target name="apidocs" depends="init">
<echo>Creating api documentation using PHP documentor</echo>
<echo>Writing to ${sabredav.apidocspath}</echo>
<phpdoc title="SabreDAV API documentation"
destdir="${sabredav.apidocspath}"
sourcecode="false"
output="HTML:frames:phphtmllib">
<fileset dir="./lib">
<include name="**/*.php" />
</fileset>
<projdocfileset dir=".">
<include name="ChangeLog" />
<include name="LICENSE" />
</projdocfileset>
</phpdoc>
</target>
<target name="init">
<!-- This sets SabreDAV version information -->
<adhoc-task name="sabredav-version"><![CDATA[
class SabreDAV_VersionTask extends Task {
public function main() {
include_once 'lib/Sabre/DAV/Version.php';
$this->getProject()->setNewProperty('sabredav.version',Sabre_DAV_Version::VERSION);
$this->getProject()->setNewProperty('sabredav.stability',Sabre_DAV_Version::STABILITY);
$this->getProject()->setNewProperty('sabredav.ucstability',ucwords(Sabre_DAV_Version::STABILITY));
}
}
]]></adhoc-task>
<sabredav-version />
<echo>SabreDAV version ${sabredav.version}</echo>
</target>
</project>

View file

@ -0,0 +1,30 @@
{
"name": "sabre/dav",
"type": "library",
"description": "WebDAV Framework for PHP",
"keywords": ["Framework", "WebDAV", "CalDAV", "CardDAV", "iCalendar"],
"homepage": "http://code.google.com/p/sabredav/",
"license" : "BSD-3-Clause",
"authors": [
{
"name": "Evert Pot",
"email": "evert@rooftopsolutions.nl",
"homepage" : "http://www.rooftopsolutions.nl/",
"role" : "Developer"
}
],
"require": {
"php": ">=5.3.1",
"sabre/vobject" : "master-dev"
},
"provide" : {
"evert/sabredav" : "2.0.0"
},
"autoload": {
"psr-0": { "Sabre": "lib/" }
},
"support" : {
"forum" : "https://groups.google.com/group/sabredav-discuss",
"source" : "https://github.com/evert/sabredav"
}
}

View file

@ -0,0 +1,336 @@
Calendar Server Extension C. Daboo
Apple
May 3, 2007
Calendar Collection Entity Tag (CTag) in CalDAV
caldav-ctag-02
Abstract
This specification defines an extension to CalDAV that provides a
fast way for a client to determine whether the contents of a calendar
collection may have changed.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Conventions Used in This Document . . . . . . . . . . . . . . . 2
3. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
3.1. Server . . . . . . . . . . . . . . . . . . . . . . . . . . 3
3.2. Client . . . . . . . . . . . . . . . . . . . . . . . . . . 3
4. New features in CalDAV . . . . . . . . . . . . . . . . . . . . 3
4.1. getctag WebDAV Property . . . . . . . . . . . . . . . . . . 4
5. Security Considerations . . . . . . . . . . . . . . . . . . . . 4
6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . . 5
7. Normative References . . . . . . . . . . . . . . . . . . . . . 5
Appendix A. Acknowledgments . . . . . . . . . . . . . . . . . . . 5
Appendix B. Change History . . . . . . . . . . . . . . . . . . . . 5
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 6
Daboo [Page 1]
CalDAV Proxy May 2007
1. Introduction
In CalDAV [RFC4791] calendar data is stored in calendar collection
resources. Clients need to "poll" calendar collections in order to
find out what has changed since the last time they examined it.
Currently that involves having to do a PROPFIND Depth:1 HTTP request,
or a CALDAV:calendar-query REPORT request. When a calendar
collection contains a large number of calendar resources those
operations become expensive on the server.
Calendar users often configure their clients to poll at short time
intervals. So polling traffic to the server will be high, even
though the frequency at which changes actually occur to a calendar is
typically low.
To improve on performance, this specification defines a new "calendar
collection entity tag" (CTag) WebDAV property that is defined on
calendar collections. When the calendar collection changes, the CTag
value changes. Thus a client can cache the CTag at some point in
time, then poll the collection only (i.e. PROPFIND Depth:0 HTTP
requests) and determine if a change has happened based on the
returned CTag value. If there is a change, it can then fall back to
doing the full (Depth:1) poll of the collection to actually determine
which resources in the collection changed.
This extension also defines CTag's on CalDAV scheduling
[I-D.desruisseaux-caldav-sched] Inbox and Outbox collections.
2. Conventions Used in This Document
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in [RFC2119].
When XML element types in the namespaces "DAV:" and
"urn:ietf:params:xml:ns:caldav" are referenced in this document
outside of the context of an XML fragment, the string "DAV:" and
"CALDAV:" will be prefixed to the element type names respectively.
The namespace "http://calendarserver.org/ns/" is used for XML
elements defined in this specification. When XML element types in
this namespace are referenced in this document outside of the context
of an XML fragment, the string "CS:" will be prefixed to the element
type names respectively.
Daboo [Page 2]
CalDAV Proxy May 2007
3. Overview
3.1. Server
For each calendar or scheduling Inbox or Outbox collection on the
server, a new CS:getctag WebDAV property is present.
The property value is an "opaque" token whose value is guaranteed to
be unique over the lifetime of any calendar or scheduling Inbox or
Outbox collection at a specific URI.
Whenever a calendar resource is added to, modified or deleted from
the calendar collection, the value of the CS:getctag property MUST
change. Typically this change will occur when the DAV:getetag
property on a child resource changes due to some protocol action. It
could be the result of a change to the body or properties of the
resource.
3.2. Client
The client starts off with an empty string as the initial value for
the cached CTag of a calendar or scheduling Inbox or Outbox
collection that it intends to synchronize with.
When polling a calendar or scheduling Inbox or Outbox collection, the
client issues a PROPFIND Depth:0 HTTP request, asking for the CS:
getctag property to be returned.
If the returned value of CS:getctag property matches the one
currently cached for the calendar or scheduling Inbox or Outbox
collection, then the collection contents have not changed and no
further action is required until the next poll.
If the returned value of CS:getctag property does not match the one
found previously, then the contents of the calendar or scheduling
Inbox or Outbox collection have changed. At that point the client
should re-issue the PROPFIND Depth:1 request to get the collection
changes in detail and the CS:getctag property value corresponding to
the new state. The new CSgetctag property value should replace the
one currently cached for that calendar or scheduling Inbox or Outbox
collection.
4. New features in CalDAV
Daboo [Page 3]
CalDAV Proxy May 2007
4.1. getctag WebDAV Property
Name: getctag
Namespace: http://calendarserver.org/ns/
Purpose: Specifies a "synchronization" token used to indicate when
the contents of a calendar or scheduling Inbox or Outbox
collection have changed.
Conformance: This property MUST be defined on a calendar or
scheduling Inbox or Outbox collection resource. It MUST be
protected and SHOULD be returned by a PROPFIND DAV:allprop request
(as defined in Section 12.14.1 of [RFC2518]).
Description: The CS:getctag property allows clients to quickly
determine if the contents of a calendar or scheduling Inbox or
Outbox collection have changed since the last time a
"synchronization" operation was done. The CS:getctag property
value MUST change each time the contents of the calendar or
scheduling Inbox or Outbox collection change, and each change MUST
result in a value that is different from any other used with that
collection URI.
Definition:
<!ELEMENT getctag #PCDATA>
Example:
<T:getctag xmlns:T="http://calendarserver.org/ns/"
>ABCD-GUID-IN-THIS-COLLECTION-20070228T122324010340</T:getctag>
5. Security Considerations
The CS:getctag property value changes whenever any resource in the
collection or scheduling Inbox or Outbox changes. Thus a change to a
resource that a user does not have read access to will result in a
change in the CTag and the user will know that a change occurred.
However, that user will not able to get additional details about
exactly what changed as WebDAV ACLs [RFC3744] will prevent that. So
this does expose the fact that there are potentially "hidden"
resources in a calendar collection, but it does not expose any
details about them.
Daboo [Page 4]
CalDAV Proxy May 2007
6. IANA Considerations
This document does not require any actions on the part of IANA.
7. Normative References
[I-D.desruisseaux-caldav-sched]
Desruisseaux, B., "Scheduling Extensions to CalDAV",
draft-desruisseaux-caldav-sched-03 (work in progress),
January 2007.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC2518] Goland, Y., Whitehead, E., Faizi, A., Carter, S., and D.
Jensen, "HTTP Extensions for Distributed Authoring --
WEBDAV", RFC 2518, February 1999.
[RFC3744] Clemm, G., Reschke, J., Sedlar, E., and J. Whitehead, "Web
Distributed Authoring and Versioning (WebDAV) Access
Control Protocol", RFC 3744, May 2004.
[RFC4791] Daboo, C., Desruisseaux, B., and L. Dusseault,
"Calendaring Extensions to WebDAV (CalDAV)", RFC 4791,
March 2007.
Appendix A. Acknowledgments
This specification is the result of discussions between the Apple
calendar server and client teams.
Appendix B. Change History
Changes from -01:
1. Updated to RFC4791 reference.
2. Added text indicating that ctag applies to schedule Inbox and
Outbox as well.
Changes from -00:
1. Relaxed requirement so that any type of change to a child
resource can trigger a CTag change (similar behavior to ETag).
Daboo [Page 5]
CalDAV Proxy May 2007
Author's Address
Cyrus Daboo
Apple Inc.
1 Infinite Loop
Cupertino, CA 95014
USA
Email: cyrus@daboo.name
URI: http://www.apple.com/
Daboo [Page 6]

View file

@ -0,0 +1,1568 @@
Calendar Server Extension C. Daboo
Apple Inc.
March 19, 2012
CalDAV: Calendar User Notifications
Abstract
This specification defines an extension to CalDAV that allows the
server to provide notifications to calendar users.
Daboo [Page 1]
CalDAV User Notifications March 2012
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 3
2. Open Issues . . . . . . . . . . . . . . . . . . . . . . . . . 3
3. Conventions Used in This Document . . . . . . . . . . . . . . 3
4. Notifications . . . . . . . . . . . . . . . . . . . . . . . . 3
4.1. Additional Principal Properties . . . . . . . . . . . . . 4
4.1.1. CS:notification-URL Property . . . . . . . . . . . . . 5
4.2. Properties on Notification Resources . . . . . . . . . . . 5
4.2.1. CS:notificationtype Property . . . . . . . . . . . . . 5
4.3. XML Element Definitions . . . . . . . . . . . . . . . . . 6
4.3.1. CS:notifications . . . . . . . . . . . . . . . . . . . 6
4.3.2. CS:notification . . . . . . . . . . . . . . . . . . . 6
4.3.3. CS:dtstamp . . . . . . . . . . . . . . . . . . . . . . 7
5. Notification Definitions . . . . . . . . . . . . . . . . . . . 7
5.1. System Status Notification . . . . . . . . . . . . . . . . 7
5.1.1. CS:systemstatus Element Definition . . . . . . . . . . 8
5.2. Quota Notification . . . . . . . . . . . . . . . . . . . . 8
5.2.1. CS:quotastatus Element Definition . . . . . . . . . . 9
5.3. Resource Changes Notification . . . . . . . . . . . . . . 10
5.3.1. CS:resource-change Element Definition . . . . . . . . 11
5.3.2. CS:calendar-changes Element Definition . . . . . . . . 15
5.3.2.1. Handling Recurrences in CS:calendar-changes . . . 17
5.3.3. CS:deleted-details Element Definition . . . . . . . . 18
5.3.4. CS:notify-changes Property . . . . . . . . . . . . . . 20
6. Security Considerations . . . . . . . . . . . . . . . . . . . 20
7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 21
8. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 21
9. References . . . . . . . . . . . . . . . . . . . . . . . . . . 21
9.1. Normative References . . . . . . . . . . . . . . . . . . . 21
9.2. Informative References . . . . . . . . . . . . . . . . . . 21
Appendix A. Examples . . . . . . . . . . . . . . . . . . . . . . 21
A.1. Resource Created . . . . . . . . . . . . . . . . . . . . . 21
A.2. Resource Updated - Property Change . . . . . . . . . . . . 22
A.3. Resource Updated - Parameter Change . . . . . . . . . . . 23
A.4. Resource Updated - Multiple Instances Change . . . . . . . 23
A.5. Resource Updated - Multiple User Change . . . . . . . . . 24
A.6. Resource Deleted . . . . . . . . . . . . . . . . . . . . . 25
A.7. Collection Created . . . . . . . . . . . . . . . . . . . . 26
A.8. Collection Updated . . . . . . . . . . . . . . . . . . . . 26
A.9. Collection Deleted . . . . . . . . . . . . . . . . . . . . 27
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 27
Daboo [Page 2]
CalDAV User Notifications March 2012
1. Introduction
CalDAV [RFC4791] provides a way for calendar users to store calendar
data and exchange this data via scheduling operations. Based on the
WebDAV [RFC4918] protocol, it also includes the ability to manage
access to calendar data via the WebDAV ACL [RFC3744] extension.
It is often useful for servers to communicate arbitrary information
to calendar users, e.g., system status, message of the day, quota
warnings, changes to shared resources made by others etc. This
specification defines a generic "notification" mechanism that allows
a server to do that. Whilst primarily aimed at CalDAV [RFC4791],
this mechanism has been designed to be adaptable to WebDAV [RFC4918].
2. Open Issues
1. Define specific child elements for system status notification,
e.g. "server-maintenance-period", "server-read-only-period",
"client-upgrade-required".
3. Conventions Used in This Document
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in [RFC2119].
When XML element types in the namespaces "DAV:" and
"urn:ietf:params:xml:ns:caldav" are referenced in this document
outside of the context of an XML fragment, the string "DAV:" and
"CALDAV:" will be prefixed to the element type names respectively.
The namespace "http://calendarserver.org/ns/" is used for XML
elements defined in this specification. When XML element types in
that namespace are referenced in this document outside of the context
of an XML fragment, the string "CS:" will be prefixed to the element
type names.
4. Notifications
When this feature is available, a CS:notification-URL (Section 4.1.1)
property appears on principal resources for those principals who are
able to receive notifications. That property specifies a single DAV:
href element whose content refers to a WebDAV collection resource.
Notification "messages" are deposited into this collection and can be
retrieved by clients and acted on accordingly.
Daboo [Page 3]
CalDAV User Notifications March 2012
The notification collection referenced by the CS:notification-URL
(Section 4.1.1) property MUST have a DAV:resourcetype property with
DAV:collection and CS:notifications (Section 4.3.1) child elements.
Notification "messages" are XML documents stored as resources in the
notification collection. Each XML document contains a CS:
notification (Section 4.3.2) element as its root. The root element
contains a CS:dtstamp element, and one additional element which
represents the type of notification being conveyed in the message.
That child element will typically contain additional content that
describes the notification.
Each notification resource has a CS:notificationtype (Section 4.2.1)
property which contains as its single child element an empty element
that matches the child element of the notification resource XML
document root. Any attributes on the child element in the XML
document are also present in the property child element.
Notifications are automatically generated by the server (perhaps in
response to a action) with an appropriate resource stored in the
notifications collection of the user to whom the notification is
targeted. Clients SHOULD monitor the notification collection looking
for new notification resources. When doing so, clients SHOULD look
at the CS:notificationtype (Section 4.2.1) property to ensure that
the notification is of a type that the client can handle. Once a
client has handled the notification in whatever way is appropriate it
SHOULD delete the notification resource. Clients SHOULD remove
notifications being displayed to a user when the notification
resource is removed from the notification collection, to enable the
user to dismiss a notification on one device and have it
automatically removed from others. Clients MUST ignore all
notifications for types they do not recognize. Servers MAY delete
notification resources on their own if they determine that the
notifications are no longer relevant or valid. Servers MAY coalesce
notifications as appropriate.
Servers MUST prevent clients from adding resources in the
notification collection.
4.1. Additional Principal Properties
This section defines new properties for WebDAV principal resources as
defined in RFC3744 [RFC3744]. These properties are likely to be
protected but the server MAY allow them to be written by appropriate
users.
Daboo [Page 4]
CalDAV User Notifications March 2012
4.1.1. CS:notification-URL Property
Name: notification-URL
Namespace: http://calendarserver.org/ns/
Purpose: Identify the URL of the notification collection owned by
the associated principal resource.
Protected: This property SHOULD be protected.
PROPFIND behavior: This property SHOULD NOT be returned by a
PROPFIND allprop request (as defined in Section 14.2 of
[RFC4918]).
COPY/MOVE behavior: This property value SHOULD be preserved in COPY
and MOVE operations.
Description: This property is needed for a client to determine where
the notification collection of the current user is located so that
processing of notification messages can occur. If not present,
then the associated calendar user is not enabled for notification
messages on the server.
Definition:
<!ELEMENT notification-URL (DAV:href)>
4.2. Properties on Notification Resources
The following new WebDAV properties are defined for notification
resources.
4.2.1. CS:notificationtype Property
Name: notificationtype
Namespace: http://calendarserver.org/ns/
Purpose: Identify the type of notification of the corresponding
resource.
Protected: This property MUST be protected.
PROPFIND behavior: This property SHOULD NOT be returned by a
PROPFIND allprop request (as defined in Section 14.2 of
[RFC4918]).
Daboo [Page 5]
CalDAV User Notifications March 2012
COPY/MOVE behavior: This property value MUST be preserved in COPY
and MOVE operations.
Description: This property allows a client, via a PROPFIND Depth:1
request, to quickly find notification messages that the client can
handle in a notification collection. The single child element is
the notification resource root element's child defining the
notification itself. This element MUST be empty, though any
attributes on the element in the notification resource MUST be
present in the property element.
Definition:
<!ELEMENT notificationtype ANY>
<!-- Child elements are empty but will have appropriate attributes.
Any valid notification message child element can appear.-->
4.3. XML Element Definitions
4.3.1. CS:notifications
Name: notifications
Namespace: http://calendarserver.org/ns/
Purpose: Indicates a notification collection.
Description: This XML element is used in a DAV:resourcetype element
to indicate that the corresponding resource is a notification
collection.
Definition:
<!ELEMENT notifications EMPTY>
4.3.2. CS:notification
Name: notification
Namespace: http://calendarserver.org/ns/
Purpose: Notification message root element.
Description: The root element used in notification resources.
Daboo [Page 6]
CalDAV User Notifications March 2012
Definition:
<!ELEMENT notification (dtstamp, XXX) >
<!-- Any notification type element can appear after
CS:dtstamp -->
4.3.3. CS:dtstamp
Name: dtstamp
Namespace: http://calendarserver.org/ns/
Purpose: Date-time stamp.
Description: Contains the date-time stamp corresponding to the
creation of a notification message, using the format defined in
[RFC3339], or the "compact" format without "-" and ":" characters
between date and time elements, respectively.
Definition:
<!ELEMENT dtstamp (#PCDATA)>
<!-- Value is a date-time in UTZ as per [RFC3339] with
"compact" format allowed.-->
5. Notification Definitions
This section defines a set of common notification types.
5.1. System Status Notification
The system status notification is used to convey a URI and/or textual
description to the user. The assumption is that the URI points to a
webpage where current system status is described in detail, with the
provided description being a summary of that. A "type" attribute on
the element is used to indicate the importance of the current status
notification, and has the values "low", "medium" and "high",
representing the increasing level of importance of the message
respectively.
Servers might have knowledge of specific calendar user language
preferences, in which case it MAY localise the CS:description value
as appropriate based on the calendar user accessing the notification,
but if it does, it SHOULD include an xml:lang attribute on the CS:
description element to indicate what language is being used.
Daboo [Page 7]
CalDAV User Notifications March 2012
5.1.1. CS:systemstatus Element Definition
Name: systemstatus
Namespace: http://calendarserver.org/ns/
Purpose: Indicates a system status notification.
Description: This XML element is used in a CS:notification element
to describe a system status notification.
Definition:
<!ELEMENT systemstatus (DAV:href?, CS:description?)>
<!ATTLIST systemstatus type (low | medium | high) "low">
<!ELEMENT description CDATA>
<!-- One of DAV:href of CS:description MUST be present -->
Example: This is an example of the body of a notification resource
for an emergency system outage:
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:12:53-05:00</CS:dtstamp>
<CS:systemstatus type="high">
<D:href>http://example.com/emergency_shutdown.html</D:href>
<CS:description xml:lang='en_US'
>Emergency shutdown now</CS:description>
</CS:systemstatus>
</CS:notification>
Example: This is an example of the WebDAV property on the example
notification resource above:
<?xml version="1.0" encoding="UTF-8"?>
<CS:notificationtype xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:systemstatus type="high" />
</CS:notificationtype>
5.2. Quota Notification
The quota notification is used to convey information about the status
of one or more quotas for the user. The notification contains
elements for different types of quota being reported to the user. In
Daboo [Page 8]
CalDAV User Notifications March 2012
some cases these may be warnings (e.g., a user getting to 80% of
their quota limit), or in other cases errors (e.g., a user exceeding
their quota).
5.2.1. CS:quotastatus Element Definition
Name: quotastatus
Namespace: http://calendarserver.org/ns/
Purpose: Indicates a quota status notification.
Description: This XML element is used in a CS:notification element
to describe a quota status notification. The CS:quota-percent-
used element contains an integer greater than or equal to zero.
If the value is greater than or equal to 100, then the user's
quota has been reached or exceeded. The DAV:href element contains
a URI for a webpage where the user can go to get further
information about their quota status or take corrective action.
Definition:
<!ELEMENT quota-status (quota+)>
<!ELEMENT quota (quota-type, quota-percent-used?,
quota-count?, DAV:href?)>
<!ATTLIST quota type (warning | exceeded) "exceeded">
<!ELEMENT quota-type ANY>
<!-- Child elements are application specific -->
<!ELEMENT quota-percent-used CDATA>
<!-- Integer value greater than or equal to zero -->
<!ELEMENT quota-count CDATA>
<!-- Integer value greater than or equal to zero -->
Example: This is an example of the body of a notification resource
for a quota warning:
Daboo [Page 9]
CalDAV User Notifications March 2012
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:12:53-05:00</CS:dtstamp>
<CS:quota-status>
<CS:quota type="warning">
<CS:quota-type><CS:attachments /></CS:quota-type>
<CS:quota-percent-used>80</CS:quota-percent-used>
<D:href>https://example.com/your-account.html</D:href>
</CS:quota>
</CS:quota-status>
</CS:notification>
Example: This is an example of the body of a notification resource
for a quota that has been exceeded, and a count-based limit that
is shown as a warning:
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:12:53-05:00</CS:dtstamp>
<CS:quota-status>
<CS:quota type="exceeded">
<CS:quota-type><CS:attachments /></CS:quota-type>
<CS:quota-percent-used>102</CS:quota-percent-used>
<D:href>https://example.com/fix-account.html</D:href>
</CS:quota>
<CS:quota type="warning">
<CS:quota-type><CS:events /></CS:quota-type>
<CS:quota-percent-used>82</CS:quota-percent-used>
<CS:quota-count>4980</CS:quota-count>
<D:href>https://example.com/buy-more-space.html</D:href>
</CS:quota>
</CS:quota-status>
</CS:notification>
5.3. Resource Changes Notification
The resource change notification is used to inform the user of new,
updated or deleted resources caused by changes made by someone else
(note: servers MUST NOT generate notifications to users for changes
they themselves make, though the possibility of an automated process
acting on behalf of a user needs to be considered). This
notification can be used by clients to show changes that a user can
acknowledge in their own time. When the notification is present, it
can be displayed on all devices a user is accessing their data from.
When the user acknowledges and dismisses the notification on one
device, other devices SHOULD also remove the notification when they
Daboo [Page 10]
CalDAV User Notifications March 2012
next synchronize the notification collection.
A new WebDAV property CS:notify-changes (Section 5.3.4) is defined
for calendar collections. This allows users to enable or disable the
sending of resource change notifications for the calendar and its
child resources. Servers MUST allow users to set this property on a
per-user basis on any calendars accessible to them. Servers MUST
honor the chosen setting to enable or disable change notifications.
Servers can send notifications for calendar object resources, and
ones for calendar collections. Servers SHOULD coalesce notifications
that refer to the same resource into a single notification resource,
containing multiple CS:created, CS:updated or CS:deleted elements all
with the same DAV:href child element value. Servers MAY coalesce
changes to multiple resources into a change notification for the
parent collection of those resources and use a CS:collection-changes
element to indicate the number of individual resources that changed.
5.3.1. CS:resource-change Element Definition
Name: resource-change
Namespace: http://calendarserver.org/ns/
Purpose: Indicates that resources have been created, updated or
deleted.
Description: This XML element is used in a CS:notification element
to describe a resource change notification. It can describe a
change directly to a calendar object resource or to a calendar
collection.
When used for a calendar object resource change, it can contain
one of the CS:created, or CS:deleted elements, or multiple CS:
updated elements, which indicate a created, deleted or updated
resource, respectively. The DAV:href element within those
elements, contains the URI of the changed resource, optional
information about who changed the resource and when that change
was made (the CS:changed-by element), and information specific to
the nature of the change. Servers SHOULD coalesce resource change
notifications for the same resource into a single notification
resource where possible. The CS:updated element optionally
contains CS:content and/or DAV:prop elements to indicate a change
to the body of the resource or resource WebDAV properties,
respectively. The DAV:prop element MAY contain a list of property
elements to indicate which properties changed. The CS:updated
element can also contain zero or more CS:calendar-changes elements
to list details of the changes. If no CS:calendar-changes element
Daboo [Page 11]
CalDAV User Notifications March 2012
is present, the specific details are not provided, and clients
will need to assume that some set of changes occurred, but the
server is unwilling to disclose the full details. The CS:deleted
element can also contain zero or more CS:deleted-details elements
to list details of the deleted resource.
When used for a calendar collection change, it can contain a CS:
collection-changes element. The DAV:href element within that
element, contains the URI of the changed calendar collection. The
DAV:prop element indicates a change to WebDAV properties on the
calendar collection resource. The CS:child-created, CS:child-
updated, and CS:child-deleted elements each contain a positive
integer value indicating how many child resources were added,
updated or deleted in the collection, respectively.
Definition:
Daboo [Page 12]
CalDAV User Notifications March 2012
<!ELEMENT resource-change (created | updated+ | deleted |
collection-changes)>
<!ELEMENT created (DAV:href, changed-by?, ANY)>
<!ELEMENT updated (DAV:href, changed-by?, content?,
DAV:prop?, calendar-changes*)>
<!ELEMENT content EMPTY>
<!ELEMENT deleted (DAV:href, changed-by?, deleted-details)>
<!ELEMENT changed-by (common-name | (first-name, last-name),
dtstamp?, DAV:href)>
<!ELEMENT common-name CDATA>
<!ELEMENT first-name CDATA>
<!ELEMENT last-name CDATA>
<!-- CS:changed-by indicates who made the change that caused the
notification. CS:first-name and CS:last-name are the first
and last names of the corresponding user. or the
CS:common-name is the overall display name. CS:dtstamp is the
time in UTC when the change was made. The DAV:href element
is the principal URI or email address of the user who made
the change. -->
<!ELEMENT collection-changes (DAV:href, changed-by*, DAV:prop?,
child-created?, child-updated?,
child-deleted?>
<!-- When coalescing changes from multiple users, the changed-by
element can appear more than once. -->
<!ELEMENT child-created CDATA>
<!ELEMENT child-updated CDATA>
<!ELEMENT child-deleted CDATA>
<!-- Each of the three elements above MUST contain a positive,
non-zero integer value indicate the total number of changes
being reported for the collection. -->
Example: This is an example of the body of a notification resource
for changes where one resource has been created:
Daboo [Page 13]
CalDAV User Notifications March 2012
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:51:14-05:00</CS:dtstamp>
<CS:resource-change>
<CS:created>
<D:href>http://example.com/cyrus/calendar/new.ics</D:href>
<CS:changed-by>
<CS:common-name>Cyrus Daboo</CS:common-name>
<D:href>/principals/cyrusdaboo</D:href>
</CS:changed-by>
</CS:created>
</CS:resource-change>
</CS:notification>
Example: This is an example of the body of a notification resource
for changes where a resource has been updated twice. One of the
updated resources elements contains additional information
indicating which recurrence instances in the iCalendar data were
changed:
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:51:14-05:00</CS:dtstamp>
<CS:resource-change>
<CS:updated>
<D:href>http://example.com/cyrus/calendar/event.ics</D:href>
<CS:changed-by>
<CS:first-name>Oliver</CS:first-name>
<CS:last-name>Daboo</CS:last-name>
<D:href>mailto:oliver@example.com</D:href>
</CS:changed-by>
</CS:updated>
<CS:updated>
<D:href>http://example.com/cyrus/calendar/event.ics</D:href>
<CS:changed-by>
<CS:first-name>Eleanor</CS:first-name>
<CS:last-name>Daboo</CS:last-name>
<D:href>mailto:eleanor@example.com</D:href>
</CS:changed-by>
</CS:updated>
</CS:resource-change>
</CS:notification>
Daboo [Page 14]
CalDAV User Notifications March 2012
Example: This is an example of the body of a notification resource
for changes where one resource has been deleted:
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:51:14-05:00</CS:dtstamp>
<CS:resource-change>
<CS:deleted>
<D:href>http://example.com/cyrus/calendar/old.ics</D:href>
<CS:changed-by>
<CS:first-name>Cyrus</CS:first-name>
<CS:last-name>Daboo</CS:last-name>
<D:href>/principals/cyrusdaboo</D:href>
</CS:changed-by>
</CS:deleted>
</CS:resource-change>
</CS:notification>
Example: This example is the same as the previous three, except that
all the individual resource changes have been coalesced into a
single notification about changes to the parent calendar
collection:
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:51:14-05:00</CS:dtstamp>
<CS:resource-change>
<CS:collection-changes>
<D:href>http://example.com/cyrus/calendar/</D:href>
<CS:child-created>1</CS:child-created>
<CS:child-updated>2</CS:child-updated>
<CS:child-deleted>1</CS:child-deleted>
</CS:collection-changes>
</CS:resource-change>
</CS:notification>
5.3.2. CS:calendar-changes Element Definition
Name: calendar-changes
Namespace: http://calendarserver.org/ns/
Purpose: Indicates which portions of an calendar object resource
have changed, or provides details of deleted calendar object
resources.
Daboo [Page 15]
CalDAV User Notifications March 2012
Description: This XML element is used in a CS:updated element to
describe how a calendar object resource changed, or in a CS:
deleted element to provide details of a deleted resource. It can
identify the master instance, or individual recurrence instances,
and for each indicate which iCalendar properties and parameters
changed during the update for which the notification was
generated. For details of handling recurrences please see
Section 5.3.2.1.
Definition:
<!ELEMENT calendar-changes (recurrence+) >
<!ELEMENT recurrence
((master | recurrenceid), added?, removed?, changes?)>
<!-- Which instances were affected by the change,
and details on the per-instance changes -->
<!ELEMENT master EMPTY>
<!-- The "master" instance was affected -->
<!ELEMENT recurrenceid CDATA>
<!-- RECURRENCE-ID value in iCalendar form (in UTC if a
non-floating DATE-TIME value) for the affected instance -->
<!ELEMENT added EMPTY>
<!-- The component was added -->
<!ELEMENT removed EMPTY>
<!-- The component was removed -->
<!ELEMENT changes changed-property*>
<!-- Detailed changes in the iCalendar data -->
<!ELEMENT changed-property changed-parameter*>
<!ATTLIST changed-property name PCDATA>
<!-- An iCalendar property changed -->
<!ELEMENT changed-parameter EMPTY>
<!ATTLIST changed-parameter name PCDATA>
<!-- An iCalendar property parameter changed -->
Example: This example indicates that a non-recurring component, or
the master component in a recurring component, was changed and
that the change was to the "SUMMARY" iCalendar property.
Daboo [Page 16]
CalDAV User Notifications March 2012
<CS:calendar-changes xmlns:CS="http://calendarserver.org/ns/">
<CS:recurrence>
<CS:master/>
<CS:changes>
<CS:changed-property name="SUMMARY"/>
</CS:changes>
</CS:recurrence>
</CS:calendar-changes>
Example: This example indicates that an instance of a recurring
component was changed and that the change was to the "DTSTART"
iCalendar property.
<CS:calendar-changes xmlns:CS="http://calendarserver.org/ns/">
<CS:recurrence>
<CS:recurrenceid>20111215T160000Z</CS:recurrenceid>
<CS:changes>
<CS:changed-property name="DTSTART"/>
</CS:changes>
</CS:recurrence>
</CS:calendar-changes>
5.3.2.1. Handling Recurrences in CS:calendar-changes
Changes to recurring components can be complex. This section
describes the possible set of changes that could occur, and what the
CS:calendar-changes element will contain as a result.
Master exists, unchanged override added In this case, a CS:
recurrence element will be present, containing a CS:recurrence-id
element with a value equal to the RECURRENCE-ID property value (in
UTC) of the added component. A CS:added element will be present.
There will not be any CS:removed or CS:changes elements.
Master exists, changed override added In this case, a CS:recurrence
element will be present, containing a CS:recurrence-id element
with a value equal to the RECURRENCE-ID property value (in UTC) of
the added component. Both CS:added and CS:changes elements will
be present. There will not be a CS:removed element.
Master exists, override changed In this case, a CS:recurrence
element will be present, containing a CS:recurrence-id element
with a value equal to the RECURRENCE-ID property value (in UTC) of
the added component. A CS:changes element will be present. There
will not be any CS:added or CS:removed elements.
Daboo [Page 17]
CalDAV User Notifications March 2012
Master exists, override removed In this case, a CS:recurrence
element will be present, containing a CS:recurrence-id element
with a value equal to the RECURRENCE-ID property value (in UTC) of
the added component. A CS:removed element will be present. There
will not be a CS:added element. A CS:changes element will only be
present if the removed component differs from the "derived" master
instance.
Master exists, override cancelled In this case, a CS:recurrence
element will be present, containing a CS:recurrence-id element
with a value equal to the RECURRENCE-ID property value (in UTC) of
the added component. A CS:removed element will be present. There
will not be any CS:added or CS:changes element. There will also
be a CS:master element present, with an appropriate CS:changes
element, likely covering a change to "RRULE" or addition of
"EXDATE" properties.
Master does not exist, override added In this case, a CS:recurrence
element will be present, containing a CS:recurrence-id element
with a value equal to the RECURRENCE-ID property value (in UTC) of
the added component. A CS:added element will be present. There
will not be a CS:removed or CS:changes element.
Master does not exist, override changed In this case, a CS:
recurrence element will be present, containing a CS:recurrence-id
element with a value equal to the RECURRENCE-ID property value (in
UTC) of the added component. A CS:changes element will be
present. There will not be any CS:added or CS:removed elements.
Master does not exist, override removed In this case, a CS:
recurrence element will be present, containing a CS:recurrence-id
element with a value equal to the RECURRENCE-ID property value (in
UTC) of the added component. A CS:removed element will be
present. There will not be any CS:added or CS:changes element.
5.3.3. CS:deleted-details Element Definition
Name: deleted-details
Namespace: http://calendarserver.org/ns/
Purpose: Provides summary information about a deleted resource or
collection.
Description: This XML element is used in a CS:deleted element to
describe useful information about a deleted resource or
collection, so clients can provide a meaningful notification
message to users. This element has two variants: one for deletion
Daboo [Page 18]
CalDAV User Notifications March 2012
of a calendar object resource, the other for deletion of a
calendar collection.
Definition:
<!ELEMENT deleted-details ((deleted-component,
deleted-summary,
deleted-next-instance?,
deleted-had-more-instances?) |
deleted-displayname)>
<!-- deleted-displayname is used for a collection delete, the other
elements used for a resource delete. -->
<!ELEMENT deleted-component CDATA>
<!-- The main calendar component type of the deleted
resource, e.g., "VEVENT", "VTODO" -->
<!ELEMENT deleted-summary CDATA>
<!-- Indicates the "SUMMARY" of the next future instance at the
time of deletion, or the previous instance if no future
instances existed at the time of deletion. -->
<!ELEMENT deleted-next-instance CDATA>
<!ATTLIST deleted-next-instance tzid PCDATA>
<!-- If present, indicates when the next deleted instance would
have occurred. For a VEVENT that would be the DTSTART value,
for a VTODO that would be either DTSTART or DUE, if present.
In each case the value must match the value in the iCalendar
data, and any TZID iCalendar property parameter value must
be included in the tzid XML element attribute value. -->
<!ELEMENT deleted-had-more-instances EMPTY>
<!-- If present indicates that there was more than one future
instances still to occur at the time of deletion. -->
<!ELEMENT deleted-displayname CDATA>
<!-- The DAV:getdisplayname property for the collection that
was deleted. -->
Example: This example indicates deletion of a non-recurring event
that was yet to occur at the time of deletion.
<CS:deleted-details xmlns:CS="http://calendarserver.org/ns/">
<CS:deleted-component>VEVENT</CS:deleted-component>
<CS:deleted-summary>Birthday Party</CS:deleted-summary>
<CS:deleted-next-instance tzid="America/New_York
>20120505T120000</CS:deleted-next-instance>
</CS:deleted-details>
Daboo [Page 19]
CalDAV User Notifications March 2012
Example: This example indicates deletion of a calendar.
<CS:deleted-details xmlns:CS="http://calendarserver.org/ns/">
<CS:deleted-displayname>Holidays</CS:deleted-displayname>
</CS:deleted-details>
5.3.4. CS:notify-changes Property
Name: notify-changes
Namespace: http://calendarserver.org/ns/
Purpose: Allows a user to specify whether resource change
notifications are generated by the server.
Protected: This property MUST NOT be protected.
PROPFIND behavior: This property SHOULD NOT be returned by a
PROPFIND allprop request (as defined in Section 14.2 of
[RFC4918]).
COPY/MOVE behavior: This property value MUST be preserved in COPY
and MOVE operations.
Description: This property allows a user to enable or disable the
server generation of resource change notifications for the
calendar collection, and all its child resources, on which the
property resides. If the property is not present on a calendar
collection, the client and server MUST assume that resource change
notifications are enabled.
Definition:
<!ELEMENT notify-changes (true|false)>
<!ELEMENT true EMPTY>
<!ELEMENT false EMPTY>
<!-- true - notifications enabled,
false - notifications disabled -->
6. Security Considerations
Some notification mechanisms might allow a user to trigger a
notification to be delivered to other users (e.g., an invitation to
share a calendar). In such cases servers MUST ensure that suitable
limits are placed on the number and frequency of such user generated
notifications.
Daboo [Page 20]
CalDAV User Notifications March 2012
TBD: More?
7. IANA Considerations
This document does not require any actions on the part of IANA.
8. Acknowledgments
This specification is the result of discussions between the various
Apple calendar server and client teams.
9. References
9.1. Normative References
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC3339] Klyne, G., Ed. and C. Newman, "Date and Time on the
Internet: Timestamps", RFC 3339, July 2002.
[RFC4918] Dusseault, L., "HTTP Extensions for Web Distributed
Authoring and Versioning (WebDAV)", RFC 4918, June 2007.
9.2. Informative References
[RFC3744] Clemm, G., Reschke, J., Sedlar, E., and J. Whitehead, "Web
Distributed Authoring and Versioning (WebDAV)
Access Control Protocol", RFC 3744, May 2004.
[RFC4791] Daboo, C., Desruisseaux, B., and L. Dusseault,
"Calendaring Extensions to WebDAV (CalDAV)", RFC 4791,
March 2007.
Appendix A. Examples
This section provides more detailed examples of resource change
notifications for illustrative purposes only.
A.1. Resource Created
This is an example of the body of a notification resource where one
resource has been created.
Daboo [Page 21]
CalDAV User Notifications March 2012
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:51:14-05:00</CS:dtstamp>
<CS:resource-change>
<CS:created>
<D:href>http://example.com/cyrus/calendar/new.ics</D:href>
<CS:changed-by>
<CS:first-name>Cyrus</CS:first-name>
<CS:last-name>Daboo</CS:last-name>
<D:href>/principals/cyrusdaboo</D:href>
</CS:changed-by>
</CS:created>
</CS:resource-change>
</CS:notification>
A.2. Resource Updated - Property Change
This is an example of the body of a notification resource where one
non-recurring event has had its "DTSTART" and "SUMMARY" iCalendar
property values changed.
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:51:14-05:00</CS:dtstamp>
<CS:resource-change>
<CS:updated>
<D:href>http://example.com/cyrus/calendar/new.ics</D:href>
<CS:changed-by>
<CS:first-name>Cyrus</CS:first-name>
<CS:last-name>Daboo</CS:last-name>
<D:href>/principals/cyrusdaboo</D:href>
</CS:changed-by>
<CS:calendar-changes>
<CS:recurrence>
<CS:master/>
<CS:changes>
<CS:changed-property name="DTSTART"/>
<CS:changed-property name="SUMMARY"/>
</CS:changes>
</CS:recurrence>
</CS:calendar-changes>
</CS:updated>
</CS:resource-change>
</CS:notification>
Daboo [Page 22]
CalDAV User Notifications March 2012
A.3. Resource Updated - Parameter Change
This is an example of the body of a notification resource where one
non-recurring event has had the "PARTSTAT" iCalendar property
parameter on an "ATTENDEE" property changed, and a "TRANSP" property
added.
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:51:14-05:00</CS:dtstamp>
<CS:resource-change>
<CS:updated>
<D:href>http://example.com/cyrus/calendar/new.ics</D:href>
<CS:changed-by>
<CS:first-name>Cyrus</CS:first-name>
<CS:last-name>Daboo</CS:last-name>
<D:href>/principals/cyrusdaboo</D:href>
</CS:changed-by>
<CS:calendar-changes>
<CS:recurrence>
<CS:master/>
<CS:added>
<CS:changed-property name="TRANSP"/>
</CS:added>
<CS:changes>
<CS:changed-property name="ATTENDEE">
<CS:changed-parameter name="PARTSTAT"/>
</CS:changed-property>
</CS:changes>
</CS:recurrence>
</CS:calendar-changes>
</CS:updated>
</CS:resource-change>
</CS:notification>
A.4. Resource Updated - Multiple Instances Change
This is an example of the body of a notification resource where two
instances of a recurring event have their "DTSTART" and "SUMMARY"
iCalendar property values changed.
Daboo [Page 23]
CalDAV User Notifications March 2012
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:51:14-05:00</CS:dtstamp>
<CS:resource-change>
<CS:updated>
<D:href>http://example.com/cyrus/calendar/new.ics</D:href>
<CS:changed-by>
<CS:first-name>Cyrus</CS:first-name>
<CS:last-name>Daboo</CS:last-name>
<D:href>/principals/cyrusdaboo</D:href>
</CS:changed-by>
<CS:calendar-changes>
<CS:recurrence>
<CS:recurrenceid>20120209T170000Z</CS:recurrenceid>
<CS:changes>
<CS:changed-property name="DTSTART"/>
<CS:changed-property name="SUMMARY"/>
</CS:changes>
</CS:recurrence>
<CS:recurrence>
<CS:recurrenceid>20120210T170000Z</CS:recurrenceid>
<CS:changes>
<CS:changed-property name="DTSTART"/>
<CS:changed-property name="SUMMARY"/>
</CS:changes>
</CS:recurrence>
</CS:calendar-changes>
</CS:updated>
</CS:resource-change>
</CS:notification>
A.5. Resource Updated - Multiple User Change
This is an example of the body of a notification resource where two
instances of a recurring event have their "DTSTART" and "SUMMARY"
iCalendar property values changed. Each instance was changed by a
different user.
Daboo [Page 24]
CalDAV User Notifications March 2012
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:51:14-05:00</CS:dtstamp>
<CS:resource-change>
<CS:updated>
<D:href>http://example.com/cyrus/calendar/new.ics</D:href>
<CS:changed-by>
<CS:first-name>Cyrus</CS:first-name>
<CS:last-name>Daboo</CS:last-name>
<D:href>/principals/cyrusdaboo</D:href>
</CS:changed-by>
<CS:calendar-changes>
<CS:recurrence>
<CS:recurrenceid>20120209T170000Z</CS:recurrenceid>
<CS:changes>
<CS:changed-property name="DTSTART"/>
<CS:changed-property name="SUMMARY"/>
</CS:changes>
</CS:recurrence>
</CS:calendar-changes>
</CS:updated>
<CS:updated>
<D:href>http://example.com/cyrus/calendar/new.ics</D:href>
<CS:changed-by>
<CS:first-name>Eric</CS:first-name>
<CS:last-name>York</CS:last-name>
<D:href>/principals/ericyork</D:href>
</CS:changed-by>
<CS:calendar-changes>
<CS:recurrence>
<CS:recurrenceid>20120210T170000Z</CS:recurrenceid>
<CS:changes>
<CS:changed-property name="DTSTART"/>
<CS:changed-property name="SUMMARY"/>
</CS:changes>
</CS:recurrence>
</CS:calendar-changes>
</CS:updated>
</CS:resource-change>
</CS:notification>
A.6. Resource Deleted
This is an example of the body of a notification resource where one
resource has been deleted. The resource was a VEVENT whose next
occurrence was in the future on 20120210T170000Z.
Daboo [Page 25]
CalDAV User Notifications March 2012
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:51:14-05:00</CS:dtstamp>
<CS:resource-change>
<CS:deleted>
<D:href>http://example.com/cyrus/calendar/new.ics</D:href>
<CS:changed-by>
<CS:first-name>Cyrus</CS:first-name>
<CS:last-name>Daboo</CS:last-name>
<D:href>/principals/cyrusdaboo</D:href>
</CS:changed-by>
<CS:deleted-details>
<CS:deleted-component>VEVENT</CS:deleted-component>
<CS:deleted-summary>CalDAV Meeting</CS:deleted-summary>
<CS:deleted-next-instance
>20120210T170000Z</CS:deleted-next-instance>
</CS:deleted-details>
</CS:deleted>
</CS:resource-change>
</CS:notification>
A.7. Collection Created
This is an example of the body of a notification resource where a
calendar collection has been created.
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:51:14-05:00</CS:dtstamp>
<CS:resource-change>
<CS:created>
<D:href>http://example.com/cyrus/new-calendar/</D:href>
<CS:changed-by>
<CS:first-name>Cyrus</CS:first-name>
<CS:last-name>Daboo</CS:last-name>
<D:href>/principals/cyrusdaboo</D:href>
</CS:changed-by>
</CS:created>
</CS:resource-change>
</CS:notification>
A.8. Collection Updated
This is an example of the body of a notification resource where
coalesced changes in a calendar collection are shown. In this case 1
child resource was created, 2 updated, and 1 deleted.
Daboo [Page 26]
CalDAV User Notifications March 2012
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:51:14-05:00</CS:dtstamp>
<CS:resource-change>
<CS:collection-changes>
<D:href>http://example.com/cyrus/calendar/</D:href>
<CS:child-created>1</CS:child-created>
<CS:child-updated>2</CS:child-updated>
<CS:child-deleted>1</CS:child-deleted>
</CS:collection-changes>
</CS:resource-change>
</CS:notification>
A.9. Collection Deleted
This is an example of the body of a notification resource where a
calendar collection has been deleted.
<?xml version="1.0" encoding="UTF-8"?>
<CS:notification xmlns:D="DAV:"
xmlns:CS="http://calendarserver.org/ns/">
<CS:dtstamp>2011-12-09T11:51:14-05:00</CS:dtstamp>
<CS:resource-change>
<CS:deleted>
<D:href>http://example.com/cyrus/old-calendar/</D:href>
<CS:changed-by>
<CS:first-name>Cyrus</CS:first-name>
<CS:last-name>Daboo</CS:last-name>
<D:href>/principals/cyrusdaboo</D:href>
</CS:changed-by>
<CS:deleted-details>
<CS:deleted-displayname>Holidays</CS:deleted-displayname>
</CS:deleted-details>
</CS:deleted>
</CS:resource-change>
</CS:notification>
Daboo [Page 27]
CalDAV User Notifications March 2012
Author's Address
Cyrus Daboo
Apple Inc.
1 Infinite Loop
Cupertino, CA 95014
USA
Email: cyrus@daboo.name
URI: http://www.apple.com/
Daboo [Page 28]

View file

@ -0,0 +1,560 @@
Calendar Server Extension C. Daboo
Apple Computer
May 3, 2007
Calendar User Proxy Functionality in CalDAV
caldav-cu-proxy-02
Abstract
This specification defines an extension to CalDAV that makes it easy
for clients to setup and manage calendar user proxies, using the
WebDAV Access Control List extension as a basis.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Conventions Used in This Document . . . . . . . . . . . . . . 2
3. Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
3.1. Server . . . . . . . . . . . . . . . . . . . . . . . . . . 3
3.2. Client . . . . . . . . . . . . . . . . . . . . . . . . . . 3
4. Open Issues . . . . . . . . . . . . . . . . . . . . . . . . . 4
5. New features in CalDAV . . . . . . . . . . . . . . . . . . . . 4
5.1. Proxy Principal Resource . . . . . . . . . . . . . . . . . 4
5.2. Privilege Provisioning . . . . . . . . . . . . . . . . . . 8
6. Security Considerations . . . . . . . . . . . . . . . . . . . 9
7. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 9
8. Normative References . . . . . . . . . . . . . . . . . . . . . 9
Appendix A. Acknowledgments . . . . . . . . . . . . . . . . . . . 9
Appendix B. Change History . . . . . . . . . . . . . . . . . . . 10
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 10
Daboo [Page 1]
CalDAV Proxy May 2007
1. Introduction
CalDAV [RFC4791] provides a way for calendar users to store calendar
data and exchange this data via scheduling operations. Based on the
WebDAV protocol [RFC2518], it also includes the ability to manage
access to calendar data via the WebDAV ACL extension [RFC3744].
It is often common for a calendar user to delegate some form of
responsibility for their calendar and schedules to another calendar
user (e.g., a boss allows an assistant to check a calendar or to send
and accept scheduling invites on his behalf). The user handling the
calendar data on behalf of someone else is often referred to as a
"calendar user proxy".
Whilst CalDAV does have fine-grained access control features that can
be used to setup complex sharing and management of calendars, often
the proxy behavior required is an "all-or-nothing" approach - i.e.
the proxy has access to all the calendars or to no calendars (in
which case they are of course not a proxy). So a simple way to
manage access to an entire set of calendars and scheduling ability
would be handy.
In addition, calendar user agents will often want to display to a
user who has proxy access to their calendars, or to whom they are
acting as a proxy. Again, CalDAV's access control discovery and
report features can be used to do that, but with fine-grained control
that exists, it can be hard to tell who is a "real" proxy as opposed
to someone just granted rights to some subset of calendars. Again, a
simple way to discover proxy information would be handy.
2. Conventions Used in This Document
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in [RFC2119].
When XML element types in the namespace "DAV:" are referenced in this
document outside of the context of an XML fragment, the string "DAV:"
will be prefixed to the element type names.
When XML element types in the namespaces "DAV:" and
"urn:ietf:params:xml:ns:caldav" are referenced in this document
outside of the context of an XML fragment, the string "DAV:" and
"CALDAV:" will be prefixed to the element type names respectively.
The namespace "http://calendarserver.org/ns/" is used for XML
elements defined in this specification. When XML element types in
Daboo [Page 2]
CalDAV Proxy May 2007
this namespace are referenced in this document outside of the context
of an XML fragment, the string "CS:" will be prefixed to the element
type names respectively.
3. Overview
3.1. Server
For each calendar user principal on the server, the server will
generate two group principals - "proxy groups". One is used to hold
the list of principals who have read-only proxy access to the main
principal's calendars, the other holds the list of principals who
have read-write and scheduling proxy access. NB these new group
principals would have no equivalent in Open Directory.
Privileges on each "proxy group" principal will be set so that the
"owner" has the ability to change property values.
The "proxy group" principals will be child resources of the user
principal resource with specific resource types and thus are easy to
discover. As a result the user principal resources will also be
collection resources.
When provisioning the calendar user home collection, the server will:
a. Add an ACE to the calendar home collection giving the read-only
"proxy group" inheritable read access.
b. Add an ACE to the calendar home collection giving the read-write
"proxy group" inheritable read-write access.
c. Add an ACE to each of the calendar Inbox and Outbox collections
giving the CALDAV:schedule privilege
[I-D.desruisseaux-caldav-sched] to the read-write "proxy group".
3.2. Client
A client can see who the proxies are for the current principal by
examining the principal resource for the two "proxy group" properties
and then looking at the DAV:group-member-set property of each.
The client can edit the list of proxies for the current principal by
editing the DAV:group-member-set property on the relevant "proxy
group" principal resource.
The client can find out who the current principal is a proxy for by
running a DAV:principal-match REPORT on the principal collection.
Daboo [Page 3]
CalDAV Proxy May 2007
Alternatively, the client can find out who the current principal is a
proxy for by examining the DAV:group-membership property on the
current principal resource looking for membership in other users'
"proxy groups".
4. Open Issues
1. Do we want to separate read-write access to calendars vs the
ability to schedule as a proxy?
2. We may want to restrict changing properties on the proxy group
collections to just the DAV:group-member-set property?
3. There is no way for a proxy to be able to manage the list of
proxies. We could allow the main calendar user DAV:write-acl on
their "proxy group" principals, in which case they could grant
others the right to modify the group membership.
4. Should the "proxy group" principals also be collections given
that the regular principal resources will be?
5. New features in CalDAV
5.1. Proxy Principal Resource
Each "regular" principal resource that needs to allow calendar user
proxy support MUST be a collection resource. i.e. in addition to
including the DAV:principal XML element in the DAV:resourcetype
property on the resource, it MUST also include the DAV:collection XML
element.
Each "regular" principal resource MUST contain two child resources
with names "calendar-proxy-read" and "calendar-proxy-write" (note
that these are only suggested names - the server could choose any
unique name for these). These resources are themselves principal
resources that are groups contain the list of principals for calendar
users who can act as a read-only or read-write proxy respectively.
The server MUST include the CS:calendar-proxy-read or CS:calendar-
proxy-write XML elements in the DAV:resourcetype property of the
child resources, respectively. This allows clients to discover the
"proxy group" principals by using a PROPFIND, Depth:1 request on the
current user's principal resource and requesting the DAV:resourcetype
property be returned. The element type declarations are:
Daboo [Page 4]
CalDAV Proxy May 2007
<!ELEMENT calendar-proxy-read EMPTY>
<!ELEMENT calendar-proxy-write EMPTY>
The server MUST allow the "parent" principal to change the DAV:group-
member-set property on each of the "child" "proxy group" principal
resources. When a principal is listed as a member of the "child"
resource, the server MUST include the "child" resource URI in the
DAV:group-membership property on the included principal resource.
Note that this is just "normal" behavior for a group principal.
An example principal resource layout might be:
+ /
+ principals/
+ users/
+ cyrus/
calendar-proxy-read
calendar-proxy-write
+ red/
calendar-proxy-read
calendar-proxy-write
+ wilfredo/
calendar-proxy-read
calendar-proxy-write
If the principal "cyrus" wishes to have the principal "red" act as a
calendar user proxy on his behalf and have the ability to change
items on his calendar or schedule meetings on his behalf, then he
would add the principal resource URI for "red" to the DAV:group-
member-set property of the principal resource /principals/users/
cyrus/calendar-proxy-write, giving:
<DAV:group-member-set>
<DAV:href>/principals/users/red/</DAV:href>
</DAV:group-member-set>
The DAV:group-membership property on the resource /principals/users/
red/ would be:
<DAV:group-membership>
<DAV:href>/principals/users/cyrus/calendar-proxy-write</DAV:href>
</DAV:group-membership>
If the principal "red" was also a read-only proxy for the principal
"wilfredo", then the DA:group-membership property on the resource
/principals/users/red/ would be:
Daboo [Page 5]
CalDAV Proxy May 2007
<DAV:group-membership>
<DAV:href>/principals/users/cyrus/calendar-proxy-write</DAV:href>
<DAV:href>/principals/users/wilfredo/calendar-proxy-read</DAV:href>
</DAV:group-membership>
Thus a client can discover to which principals a particular principal
is acting as a calendar user proxy for by examining the DAV:group-
membership property.
An alternative to discovering which principals a user can proxy as is
to use the WebDAV ACL principal-match report, targeted at the
principal collections available on the server.
Example:
>> Request <<
REPORT /principals/ HTTP/1.1
Host: cal.example.com
Depth: 0
Content-Type: application/xml; charset="utf-8"
Content-Length: xxxx
Authorization: Digest username="red",
realm="cal.example.com", nonce="...",
uri="/principals/", response="...", opaque="..."
<?xml version="1.0" encoding="utf-8" ?>
<D:principal-match xmlns:D="DAV:">
<D:self/>
<D:prop>
<D:resourcetype/>
</D:prop>
</D:principal-match>
Daboo [Page 6]
CalDAV Proxy May 2007
>> Response <<
HTTP/1.1 207 Multi-Status
Date: Fri, 10 Nov 2006 09:32:12 GMT
Content-Type: application/xml; charset="utf-8"
Content-Length: xxxx
<?xml version="1.0" encoding="utf-8" ?>
<D:multistatus xmlns:D="DAV:"
xmlns:A="http://calendarserver.org/ns/">
<D:response>
<D:href>/principals/users/red/</D:href>
<D:propstat>
<D:prop>
<D:resourcetype>
<D:principal/>
<D:collection/>
</D:resourcetype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
<D:response>
<D:href>/principals/users/cyrus/calendar-proxy-write</D:href>
<D:propstat>
<D:prop>
<D:resourcetype>
<D:principal/>
<A:calendar-proxy-write/>
</D:resourcetype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
<D:response>
<D:href>/principals/users/wilfredo/calendar-proxy-read</D:href>
<D:propstat>
<D:prop>
<D:resourcetype>
<D:principal/>
<A:calendar-proxy-read/>
</D:resourcetype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
</D:multistatus>
Daboo [Page 7]
CalDAV Proxy May 2007
5.2. Privilege Provisioning
In order for a calendar user proxy to be able to access the calendars
of the user they are proxying for the server MUST ensure that the
privileges on the relevant calendars are setup accordingly:
The DAV:read privilege MUST be granted for read-only and read-
write calendar user proxy principals
The DAV:write privilege MUST be granted for read-write calendar
user proxy principals.
Additionally, the CalDAV scheduling Inbox and Outbox calendar
collections for the user allowing proxy access, MUST have the CALDAV:
schedule privilege [I-D.desruisseaux-caldav-sched] granted for read-
write calendar user proxy principals.
Note that with a suitable repository layout, a server may be able to
grant the appropriate privileges on a parent collection and ensure
that all the contained collections and resources inherit that. For
example, given the following repository layout:
+ /
+ calendars/
+ users/
+ cyrus/
inbox
outbox
home
work
+ red/
inbox
outbox
work
soccer
+ wilfredo/
inbox
outbox
home
work
flying
In order for the principal "red" to act as a read-write proxy for the
principal "cyrus", the following WebDAV ACE will need to be granted
on the resource /calendars/users/cyrus/ and all children of that
resource:
Daboo [Page 8]
CalDAV Proxy May 2007
<DAV:ace>
<DAV:principal>
<DAV:href>/principals/users/cyrus/calendar-proxy-write</DAV:href>
</DAV:principal>
<DAV:privileges>
<DAV:grant><DAV:read/><DAV:write/></DAV:grant>
</DAV:privileges>
</DAV:ace>
6. Security Considerations
TBD
7. IANA Considerations
This document does not require any actions on the part of IANA.
8. Normative References
[I-D.desruisseaux-caldav-sched]
Desruisseaux, B., "Scheduling Extensions to CalDAV",
draft-desruisseaux-caldav-sched-03 (work in progress),
January 2007.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC2518] Goland, Y., Whitehead, E., Faizi, A., Carter, S., and D.
Jensen, "HTTP Extensions for Distributed Authoring --
WEBDAV", RFC 2518, February 1999.
[RFC3744] Clemm, G., Reschke, J., Sedlar, E., and J. Whitehead, "Web
Distributed Authoring and Versioning (WebDAV) Access
Control Protocol", RFC 3744, May 2004.
[RFC4791] Daboo, C., Desruisseaux, B., and L. Dusseault,
"Calendaring Extensions to WebDAV (CalDAV)", RFC 4791,
March 2007.
Appendix A. Acknowledgments
This specification is the result of discussions between the Apple
calendar server and client teams.
Daboo [Page 9]
CalDAV Proxy May 2007
Appendix B. Change History
Changes from -00:
1. Updated to RFC 4791 reference.
Changes from -00:
1. Added more details on actual CalDAV protocol changes.
2. Changed namespace from http://apple.com/ns/calendarserver/ to
http://calendarserver.org/ns/.
3. Made "proxy group" principals child resources of their "owner"
principals.
4. The "proxy group" principals now have their own resourcetype.
Author's Address
Cyrus Daboo
Apple Computer, Inc.
1 Infinite Loop
Cupertino, CA 95014
USA
Email: cyrus@daboo.name
URI: http://www.apple.com/
Daboo [Page 10]

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,560 @@
Network Working Group C. Daboo
Internet-Draft Apple Inc.
Updates: XXXX-CardDAV August 24, 2010
(if approved)
Intended status: Standards Track
Expires: February 25, 2011
CardDAV Directory Gateway Extension
draft-daboo-carddav-directory-gateway-02
Abstract
This document defines an extension to the vCard Extensions to WebDAV
(CardDAV) protocol that allows a server to expose a directory as a
read-only address book collection.
Status of this Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at http://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
This Internet-Draft will expire on February 25, 2011.
Copyright Notice
Copyright (c) 2010 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents
(http://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must
include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as
described in the Simplified BSD License.
Daboo Expires February 25, 2011 [Page 1]
Internet-Draft CardDAV Directory Gateway Extension August 2010
Table of Contents
1. Introduction and Overview . . . . . . . . . . . . . . . . . . 3
2. Conventions . . . . . . . . . . . . . . . . . . . . . . . . . 3
3. CARDDAV:directory-gateway Property . . . . . . . . . . . . . . 4
4. XML Element Definitions . . . . . . . . . . . . . . . . . . . 5
4.1. CARDDAV:directory . . . . . . . . . . . . . . . . . . . . 5
5. Client Guidelines . . . . . . . . . . . . . . . . . . . . . . 5
6. Server Guidelines . . . . . . . . . . . . . . . . . . . . . . 6
7. Security Considerations . . . . . . . . . . . . . . . . . . . 7
8. IANA Consideration . . . . . . . . . . . . . . . . . . . . . . 8
9. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 8
10. References . . . . . . . . . . . . . . . . . . . . . . . . . . 8
10.1. Normative References . . . . . . . . . . . . . . . . . . . 8
10.2. Informative References . . . . . . . . . . . . . . . . . . 9
Appendix A. Change History (to be removed prior to
publication as an RFC) . . . . . . . . . . . . . . . 9
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . . 10
Daboo Expires February 25, 2011 [Page 2]
Internet-Draft CardDAV Directory Gateway Extension August 2010
1. Introduction and Overview
The CardDAV [I-D.ietf-vcarddav-carddav] protocol defines a standard
way of accessing, managing, and sharing contact information based on
the vCard [RFC2426] format. Often, in an enterprise or service
provider environment, a directory of all users hosted on the server
(or elsewhere) is available (for example via Lightweight Directory
Access Protocol (LDAP) [RFC4510] or some direct database access). It
would be convenient for CardDAV clients if this directory were
exposed as a "global" address book on the CardDAV server so it could
be searched in the same way as personal address books are. This
specification defines a "directory gateway" feature extension to
CardDAV to enable this.
This specification adds one new WebDAV property to principal
resources that contains the URL to one or more directory gateway
address book collection resources. It is important for clients to be
able to distinguish this address book collection from others because
there are specific limitations involved in using it as described
below. To aid that, this specification defines an XML element that
can be included as a child element of the DAV:resourcetype property
of address book collections to identify them as directory gateways.
Note that this feature is in no way intended to replace full
directory access - it is meant to simply provide a convenient way for
CardDAV clients to query contact-related attributes in directory
records.
2. Conventions
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in [RFC2119].
The term "protected" is used in the Conformance field of property
definitions as defined in Section 15 of [RFC4918].
This document uses XML DTD fragments ([W3C.REC-xml-20081126], Section
3.2) as a purely notational convention. WebDAV request and response
bodies cannot be validated by a DTD due to the specific extensibility
rules defined in Section 17 of [RFC4918] and due to the fact that all
XML elements defined by this specification use the XML namespace name
"DAV:". In particular:
1. element names use the "DAV:" namespace,
Daboo Expires February 25, 2011 [Page 3]
Internet-Draft CardDAV Directory Gateway Extension August 2010
2. element ordering is irrelevant unless explicitly stated,
3. extension elements (elements not already defined as valid child
elements) may be added anywhere, except when explicitly stated
otherwise,
4. extension attributes (attributes not already defined as valid for
this element) may be added anywhere, except when explicitly
stated otherwise.
When XML element types in the namespaces "DAV:" and
"urn:ietf:params:xml:ns:carddav" are referenced in this document
outside of the context of an XML fragment, the strings "DAV:" and
"CARDDAV:" will be prefixed to the element types, respectively.
3. CARDDAV:directory-gateway Property
Name: directory-gateway
Namespace: urn:ietf:params:xml:ns:carddav
Purpose: Identifies URLs of CardDAV address book collections acting
as a directory gateway for the server.
Protected: MUST be protected.
allprop behavior: SHOULD NOT be returned by a PROPFIND DAV:allprop
request.
Description: The CARDDAV:directory-gateway identifies address book
collection resources that are directory gateway address books for
the server.
Definition:
<!ELEMENT directory-gateway (DAV:href*)>
Example:
<C:directory-gateway xmlns:D="DAV:"
xmlns:C="urn:ietf:params:xml:ns:carddav">
<D:href>/directory</D:href>
</C:directory-gateway>
Daboo Expires February 25, 2011 [Page 4]
Internet-Draft CardDAV Directory Gateway Extension August 2010
4. XML Element Definitions
4.1. CARDDAV:directory
Name: directory
Namespace: urn:ietf:params:xml:ns:carddav
Purpose: Used to indicate that an address book collection is a
directory gateway.
Description: This element appears in the DAV:resourcetype property
on a address book collection resources that are directory
gateways. Clients can use the presence of this element to
identify directory gateway collections when doing PROPFINDs to
list collection contents.
Definition:
<!ELEMENT directory EMPTY>
Example:
<D:resourcetype xmlns:D="DAV:"
xmlns:C="urn:ietf:params:xml:ns:carddav">
<D:collection/>
<C:addressbook/>
<C:directory/>
</D:resourcetype>
5. Client Guidelines
Clients wishing to make use of directory gateway address books can
request the CARDDAV:directory-gateway property (Section 3) when
examining other properties on the principal resource for the user.
If the property is not present, then the directory gateway feature is
not supported by the server at that time.
Clients can also detect the presence of directory gateway address
book collections by retrieving the DAV:resourcetype property on
collections that it lists, and look for the presence of the CARDDAV:
directory element (Section 4.1).
Since the directory being exposed via a directory gateway address
book collection could be large, clients SHOULD limit the number of
results returned in an CARDDAV:addressbook-query REPORT as defined in
Section 8.6.1 of [I-D.ietf-vcarddav-carddav].
Daboo Expires February 25, 2011 [Page 5]
Internet-Draft CardDAV Directory Gateway Extension August 2010
Clients MUST treat the directory gateway address book collection as a
read-only collection, so HTTP methods that modify resource data or
properties in the address book collection MUST NOT be used.
Clients SHOULD NOT attempt to cache the entire contents of the
directory gateway address book collection resource by retrieving all
resources, or trying to examine all the properties of all resources
(e.g., via a PROPFIND Depth:1 request). Instead, CARDDAV:
addressbook-query REPORTs are used to search for specific address
book object resources, and CARDDAV:multiget REPORTs and individual
GET requests can be made to retrieve the actual vCard data for
address book object resources found via a query.
When presenting directory gateway collections to the user, clients
SHOULD use the DAV:displayname property on the corresponding address
book collections as the name of the directory gateway. This is
important in the case where more than one directory gateway is
available. Clients MAY also provide descriptive information about
each directory gateway by examining the CARDDAV:addressbook-
description property (see Section 6.2.1 of
[I-D.ietf-vcarddav-carddav]) on the resource.
6. Server Guidelines
Servers wishing to expose a directory gateway as an address book
collection MUST include the CARDDAV:directory-gateway property on all
principal resources of users expected to use the feature.
Since the directory being exposed via the directory gateway address
book collection could be large, servers SHOULD truncate the number of
results returned in an CARDDAV:addressbook-query REPORT as defined in
Section 8.6.2 of [I-D.ietf-vcarddav-carddav]. In addition, servers
SHOULD disallow requests that effectively enumerate the collection
contents (e.g., PROPFIND Depth:1, trivial CARDDAV:addressbook-query,
DAV:sync-collection REPORT).
Servers need to expose the directory information as a set of address
book object resources in the directory gateway address book
collection resource. To do that, a mapping between the directory
record format and the vCard data has to be applied. In general, only
directory record attributes that have a direct equivalent in vCard
SHOULD be mapped. It is up to individual implementations to
determine which attributes to map. But in all cases servers MUST
generate valid vCard data as returned to the client. In addition, as
required by CardDAV, the UID vCard property MUST be present in the
vCard data, and this value MUST be persistent from query to query for
the same directory record.
Daboo Expires February 25, 2011 [Page 6]
Internet-Draft CardDAV Directory Gateway Extension August 2010
Multiple directory sources could be available to the server. The
server MAY use a single directory gateway resource to aggregate
results from each directory source. When doing so care is needed
when dealing with potential records that refer to the same entity.
Servers MAY suppress any duplicates that they are able to determine
themselves. Alternatively, multiple directory sources can be exposed
as separate directory gateway resources.
For any directory source, a server MAY expose multiple directory
gateway resources where each represents a different query "scope" for
the directory. Different scopes MAY be offered to different
principals on the server. For example, the server might expose an
entire company directory for searching as the resource "/directory-
all" to all principals, but then provide "/directory-department-XYZ"
as another directory gateway that has a search scope that implicitly
limits the search results to just the "XYZ" department. Users in
that department would then have a CARDDAV:directory-gateway property
on their principal resource that included the "/directory-department-
XYZ" resource. Users in other departments would have corresponding
directory gateway resources available to them.
Records in a directory can include data for more than just people,
e.g, resources such as rooms or projectors, groups, computer systems
etc. It is up to individual implementations to determine the most
appropriate "scope" for the data returned via the directory gateway
by filtering the appropriate record types. As above, servers could
choose to expose people and resources under different directory
gateway resources by implicitly limiting the search "scope" for each
of those.
Servers MAY apply implementation defined access rules to determine,
on a per-user basis, what records are returned to a particularly user
and the content of those records exposed via vCard data. This per-
user behavior is in addition to the general security requirements
detailed below.
When multiple directory gateway collections are present, servers
SHOULD provide a DAV:displayname property on each that disambiguates
them. Servers MAY include a CARDDAV:addressbook-description property
(see Section 6.2.1 of [I-D.ietf-vcarddav-carddav]) on each directory
gateway resource to provide a description of the directory and any
search "scope" that might be used, or any other useful information
for users.
7. Security Considerations
Servers MUST ensure that client requests against the directory
Daboo Expires February 25, 2011 [Page 7]
Internet-Draft CardDAV Directory Gateway Extension August 2010
gateway address book collection cannot use excessive resources (CPU,
memory, network bandwidth etc), given that the directory could be
large.
Servers MUST take care not to expose sensitive directory record
attributes in the vCard data via the directory gateway address book.
In general only those properties that have direct correspondence in
vCard SHOULD be exposed.
Servers need to determine whether it is appropriate for the directory
information to be available via CardDAV to unauthenticated users. If
not, servers MUST ensure that unauthenticated users do not have
access to the directory gateway address book object resource and its
contents. If unauthenticated access is allowed, servers MAY choose
to limit the set of vCard properties that are searchable or returned
in the address book object resources when unauthenticated requests
are made.
8. IANA Consideration
This document does not require any actions on the part of IANA.
9. Acknowledgments
10. References
10.1. Normative References
[I-D.ietf-vcarddav-carddav]
Daboo, C., "vCard Extensions to WebDAV (CardDAV)",
draft-ietf-vcarddav-carddav-10 (work in progress),
November 2009.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC2426] Dawson, F. and T. Howes, "vCard MIME Directory Profile",
RFC 2426, September 1998.
[RFC4918] Dusseault, L., "HTTP Extensions for Web Distributed
Authoring and Versioning (WebDAV)", RFC 4918, June 2007.
[W3C.REC-xml-20081126]
Paoli, J., Yergeau, F., Bray, T., Sperberg-McQueen, C.,
and E. Maler, "Extensible Markup Language (XML) 1.0 (Fifth
Daboo Expires February 25, 2011 [Page 8]
Internet-Draft CardDAV Directory Gateway Extension August 2010
Edition)", World Wide Web Consortium Recommendation REC-
xml-20081126, November 2008,
<http://www.w3.org/TR/2008/REC-xml-20081126>.
10.2. Informative References
[RFC4510] Zeilenga, K., "Lightweight Directory Access Protocol
(LDAP): Technical Specification Road Map", RFC 4510,
June 2006.
Appendix A. Change History (to be removed prior to publication as an
RFC)
Changes in -02
1. Added CARDDAV:directory element for use in DAV:resourcetype
2. Allow CARDDAV:directory-gateway to be multi-valued
3. Explain how a server could implicit "scope" queries on different
directory gateway resources
Changes in -01
1. Remove duplicated text in a couple of sections
2. Add example of LDAP/generic database as possible directory
"sources"
3. Add text to explain why the client needs to treat this as special
and thus the need for a property
4. Added text to server guidelines indicating requirements for
handling vCard UID properties
5. Added text to server guidelines explain that different record
"types" may exist in the directory and the server is free to
filter those as appropriate
6. Added text to server guidelines indicating that server are free
to aggregate directory records from multiple sources
7. Added text to server guidelines indicating that servers are free
to apply implementation defined access control to the returned
data on a per-user basis
Daboo Expires February 25, 2011 [Page 9]
Internet-Draft CardDAV Directory Gateway Extension August 2010
Author's Address
Cyrus Daboo
Apple Inc.
1 Infinite Loop
Cupertino, CA 95014
USA
Email: cyrus@daboo.name
URI: http://www.apple.com/
Daboo Expires February 25, 2011 [Page 10]

View file

@ -0,0 +1,5544 @@
Network Working Group C. Daboo
Internet-Draft Apple Inc.
Updates: 4791 (if approved) B. Desruisseaux
Intended status: Standards Track Oracle
Expires: March 10, 2012 September 7, 2011
CalDAV Scheduling Extensions to WebDAV
draft-desruisseaux-caldav-sched-10
Abstract
This document defines extensions to the CalDAV "calendar-access"
feature to specify a standard way of performing scheduling
transactions with iCalendar-based calendar components. This document
defines the "calendar-auto-schedule" feature of CalDAV.
Status of This Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at http://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
This Internet-Draft will expire on March 10, 2012.
Copyright Notice
Copyright (c) 2011 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents
(http://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents
carefully, as they describe your rights and restrictions with respect
to this document. Code Components extracted from this document must
include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as
described in the Simplified BSD License.
Daboo & Desruisseaux Expires March 10, 2012 [Page 1]
Internet-Draft CalDAV Scheduling Extensions September 2011
This document may contain material from IETF Documents or IETF
Contributions published or made publicly available before November
10, 2008. The person(s) controlling the copyright in some of this
material may not have granted the IETF Trust the right to allow
modifications of such material outside the IETF Standards Process.
Without obtaining an adequate license from the person(s) controlling
the copyright in such materials, this document may not be modified
outside the IETF Standards Process, and derivative works of it may
not be created outside the IETF Standards Process, except to format
it for publication as an RFC or to translate it into languages other
than English.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.1. Terminology . . . . . . . . . . . . . . . . . . . . . . . 6
1.2. Approach . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.3. Limitations . . . . . . . . . . . . . . . . . . . . . . . 7
1.4. Notational Conventions . . . . . . . . . . . . . . . . . . 8
1.5. XML Namespaces and Processing . . . . . . . . . . . . . . 8
2. Scheduling Process . . . . . . . . . . . . . . . . . . . . . . 10
3. Scheduling Support . . . . . . . . . . . . . . . . . . . . . . 11
3.1. Example OPTIONS Request . . . . . . . . . . . . . . . . . 11
4. Scheduling Collections . . . . . . . . . . . . . . . . . . . . 12
4.1. Scheduling Outbox Collection . . . . . . . . . . . . . . . 12
4.2. Scheduling Inbox Collection . . . . . . . . . . . . . . . 13
4.3. Calendaring Reports Extensions . . . . . . . . . . . . . . 15
5. Scheduling Transactions . . . . . . . . . . . . . . . . . . . 16
5.1. Identifying Scheduling Object Resources . . . . . . . . . 16
5.2. Handling Scheduling Object Resources . . . . . . . . . . . 16
5.2.1. Organizer Scheduling Object Resources . . . . . . . . 16
5.2.1.1. Create . . . . . . . . . . . . . . . . . . . . . . 17
5.2.1.2. Modify . . . . . . . . . . . . . . . . . . . . . . 18
5.2.1.3. Remove . . . . . . . . . . . . . . . . . . . . . . 20
5.2.2. Attendee Scheduling Object Resources . . . . . . . . . 20
5.2.2.1. Allowed Attendee Changes . . . . . . . . . . . . . 20
5.2.2.2. Create . . . . . . . . . . . . . . . . . . . . . . 21
5.2.2.3. Modify . . . . . . . . . . . . . . . . . . . . . . 22
5.2.2.4. Remove . . . . . . . . . . . . . . . . . . . . . . 23
5.2.3. HTTP Methods . . . . . . . . . . . . . . . . . . . . . 24
5.2.3.1. PUT . . . . . . . . . . . . . . . . . . . . . . . 24
5.2.3.2. COPY . . . . . . . . . . . . . . . . . . . . . . . 24
5.2.3.3. MOVE . . . . . . . . . . . . . . . . . . . . . . . 25
5.2.3.4. DELETE . . . . . . . . . . . . . . . . . . . . . . 26
5.2.4. Additional Method Preconditions . . . . . . . . . . . 26
5.2.4.1. CALDAV:unique-scheduling-object-resource
Precondition . . . . . . . . . . . . . . . . . . . 26
5.2.4.2. CALDAV:same-organizer-in-all-components
Daboo & Desruisseaux Expires March 10, 2012 [Page 2]
Internet-Draft CalDAV Scheduling Extensions September 2011
Precondition . . . . . . . . . . . . . . . . . . . 26
5.2.4.3. CALDAV:allowed-organizer-scheduling-object-chan
Precondition . . . . . . . . . . . . . . . . . . . 27
5.2.4.4. CALDAV:allowed-attendee-scheduling-object-chang
Precondition . . . . . . . . . . . . . . . . . . . 28
5.2.5. DTSTAMP and SEQUENCE Properties . . . . . . . . . . . 28
5.2.6. Restrict Recurrence Instances Sent to Attendees . . . 28
5.2.7. Forcing the Server to Send a Scheduling Message . . . 29
6. Processing Incoming Scheduling Messages . . . . . . . . . . . 30
6.1. Processing Organizer Requests, Additions, and
Cancellations . . . . . . . . . . . . . . . . . . . . . . 30
6.2. Processing Attendee Replies . . . . . . . . . . . . . . . 31
6.3. Scheduling Messages as Notifications . . . . . . . . . . . 31
6.4. Default Calendar Collection . . . . . . . . . . . . . . . 31
6.4.1. Additional Method Preconditions . . . . . . . . . . . 32
6.4.1.1. CALDAV:default-calendar-needed Precondition . . . 32
6.4.1.2. CALDAV:valid-schedule-default-calendar-URL
Precondition . . . . . . . . . . . . . . . . . . . 33
7. Request for Busy Time Information . . . . . . . . . . . . . . 34
7.1. Status Codes . . . . . . . . . . . . . . . . . . . . . . . 34
7.2. Additional Method Preconditions . . . . . . . . . . . . . 34
7.2.1. DAV:need-privileges Precondition . . . . . . . . . . . 34
7.2.2. CALDAV:supported-collection Precondition . . . . . . . 35
7.2.3. CALDAV:supported-calendar-data Precondition . . . . . 36
7.2.4. CALDAV:valid-calendar-data Precondition . . . . . . . 36
7.2.5. CALDAV:valid-scheduling-message Precondition . . . . . 37
7.2.6. CALDAV:valid-organizer Precondition . . . . . . . . . 37
7.2.7. CALDAV:max-resource-size Precondition . . . . . . . . 38
7.3. Response to a POST request . . . . . . . . . . . . . . . . 38
8. Avoiding Conflicts when Updating Scheduling Object
Resources . . . . . . . . . . . . . . . . . . . . . . . . . . 40
8.1. PUT . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
8.2. DELETE, COPY or MOVE . . . . . . . . . . . . . . . . . . . 42
9. Other Scheduling Considerations . . . . . . . . . . . . . . . 44
9.1. Attendee Participation Status . . . . . . . . . . . . . . 44
9.2. Schedule Status Values . . . . . . . . . . . . . . . . . . 45
10. Additional iCalendar Property Parameters . . . . . . . . . . . 49
10.1. Schedule Agent Parameter . . . . . . . . . . . . . . . . . 49
10.2. Schedule Force Send Parameter . . . . . . . . . . . . . . 50
10.3. Schedule Status Parameter . . . . . . . . . . . . . . . . 51
11. Additional Message Header Fields . . . . . . . . . . . . . . . 53
11.1. Schedule-Reply Request Header . . . . . . . . . . . . . . 53
11.2. Schedule-Tag Response Header . . . . . . . . . . . . . . . 53
11.3. If-Schedule-Tag-Match Request Header . . . . . . . . . . . 54
12. Additional WebDAV Properties . . . . . . . . . . . . . . . . . 55
12.1. CALDAV:schedule-calendar-transp Property . . . . . . . . . 55
12.2. CALDAV:schedule-default-calendar-URL Property . . . . . . 56
12.3. CALDAV:schedule-tag Property . . . . . . . . . . . . . . . 57
Daboo & Desruisseaux Expires March 10, 2012 [Page 3]
Internet-Draft CalDAV Scheduling Extensions September 2011
13. Scheduling Access Control . . . . . . . . . . . . . . . . . . 58
13.1. Scheduling Privileges . . . . . . . . . . . . . . . . . . 58
13.1.1. Privileges on Scheduling Inbox Collections . . . . . . 58
13.1.1.1. CALDAV:schedule-deliver Privilege . . . . . . . . 58
13.1.1.2. CALDAV:schedule-deliver-invite Privilege . . . . . 59
13.1.1.3. CALDAV:schedule-deliver-reply Privilege . . . . . 59
13.1.1.4. CALDAV:schedule-query-freebusy Privilege . . . . . 59
13.1.2. Privileges on Scheduling Outbox Collections . . . . . 59
13.1.2.1. CALDAV:schedule-send Privilege . . . . . . . . . . 59
13.1.2.2. CALDAV:schedule-send-invite Privilege . . . . . . 60
13.1.2.3. CALDAV:schedule-send-reply Privilege . . . . . . . 60
13.1.2.4. CALDAV:schedule-send-freebusy Privilege . . . . . 60
13.1.3. Aggregation of Scheduling Privileges . . . . . . . . . 60
13.2. Additional Principal Properties . . . . . . . . . . . . . 61
13.2.1. CALDAV:schedule-inbox-URL Property . . . . . . . . . . 61
13.2.2. CALDAV:schedule-outbox-URL Property . . . . . . . . . 62
13.2.3. CALDAV:calendar-user-address-set Property . . . . . . 62
13.2.4. CALDAV:calendar-user-type Property . . . . . . . . . . 63
14. XML Element Definitions . . . . . . . . . . . . . . . . . . . 65
14.1. CALDAV:schedule-response XML Element . . . . . . . . . . . 65
14.2. CALDAV:response XML Element . . . . . . . . . . . . . . . 65
14.3. CALDAV:recipient XML Element . . . . . . . . . . . . . . . 65
14.4. CALDAV:request-status XML Element . . . . . . . . . . . . 66
15. Security Considerations . . . . . . . . . . . . . . . . . . . 67
15.1. Verifying Scheduling Transactions . . . . . . . . . . . . 67
15.2. Verifying Busy Time Information Requests . . . . . . . . . 67
15.3. Privacy Issues . . . . . . . . . . . . . . . . . . . . . . 68
16. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 69
16.1. Message Header Field Registrations . . . . . . . . . . . . 69
16.1.1. Schedule-Reply . . . . . . . . . . . . . . . . . . . . 69
16.1.2. Schedule-Tag . . . . . . . . . . . . . . . . . . . . . 69
16.1.3. If-Schedule-Tag-Match . . . . . . . . . . . . . . . . 69
16.2. iCalendar Property Parameter Registrations . . . . . . . . 70
16.3. iCalendar REQUEST-STATUS Value Registrations . . . . . . . 70
16.4. Additional iCalendar Elements Registries . . . . . . . . . 70
16.4.1. Schedule Agent Values Registry . . . . . . . . . . . . 70
16.4.2. Schedule Force Send Values Registry . . . . . . . . . 71
17. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 72
18. References . . . . . . . . . . . . . . . . . . . . . . . . . . 73
18.1. Normative References . . . . . . . . . . . . . . . . . . . 73
18.2. Informative References . . . . . . . . . . . . . . . . . . 74
Appendix A. Scheduling Privileges Summary . . . . . . . . . . . . 75
A.1. Scheduling Inbox Privileges . . . . . . . . . . . . . . . 75
A.2. Scheduling Outbox Privileges . . . . . . . . . . . . . . . 75
Appendix B. Example Scheduling Transactions . . . . . . . . . . . 77
B.1. Example: Organizer Inviting Multiple Attendees . . . . . . 77
B.2. Example: Attendee Receiving an Invitation . . . . . . . . 79
B.3. Example: Attendee Replying to an Invitation . . . . . . . 81
Daboo & Desruisseaux Expires March 10, 2012 [Page 4]
Internet-Draft CalDAV Scheduling Extensions September 2011
B.4. Example: Organizer Receiving a Reply to an Invitation . . 83
B.5. Example: Organizer Requesting Busy Time Information . . . 85
B.6. Example: User Attempting to Invite Attendee on behalf
of Organizer . . . . . . . . . . . . . . . . . . . . . . . 87
B.7. Example: Attendee Declining an Instance of a Recurring
Event . . . . . . . . . . . . . . . . . . . . . . . . . . 88
B.8. Example: Attendee Removing an Instance of a Recurring
Event . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Appendix C. Changes (to be removed by RFC Editor prior to
publication) . . . . . . . . . . . . . . . . . . . . 95
C.1. Changes in -10 . . . . . . . . . . . . . . . . . . . . . . 95
C.2. Changes in -09 . . . . . . . . . . . . . . . . . . . . . . 95
C.3. Changes in -08 . . . . . . . . . . . . . . . . . . . . . . 96
C.4. Changes in -07 . . . . . . . . . . . . . . . . . . . . . . 97
C.5. Changes in -06 . . . . . . . . . . . . . . . . . . . . . . 97
C.6. Changes in -05 . . . . . . . . . . . . . . . . . . . . . . 98
Daboo & Desruisseaux Expires March 10, 2012 [Page 5]
Internet-Draft CalDAV Scheduling Extensions September 2011
1. Introduction
This document specifies extensions to the CalDAV "calendar-access"
[RFC4791] feature to enable scheduling of iCalendar-based [RFC5545]
calendar components between Calendar Users. This extension leverages
the scheduling methods defined in the iCalendar Transport-independent
Interoperability Protocol (iTIP) [RFC5546] to permit Calendar Users
to perform scheduling transactions such as schedule, reschedule,
respond to scheduling request or cancel calendar components, as well
as search for busy time information.
Discussion of this Internet-Draft is taking place on the mailing list
<https://www.ietf.org/mailman/listinfo/caldav>.
1.1. Terminology
This specification uses much of the same terminology as iCalendar
[RFC5545], iTIP [RFC5546], WebDAV [RFC4918], and CalDAV [RFC4791].
The following definitions are provided to aid the reader in
understanding this specification.
Calendar User (CU): An entity (often a human) that accesses calendar
information [RFC3283].
Calendar collection: A resource that acts as a container of
references to child calendar object resources [RFC4791].
Calendar object resource: A resource representing a calendar object
(event, to-do, journal entry, or other calendar components)
[RFC4791].
Scheduling object resource: A calendar object resource contained in
a calendar collection for which the server will take care of
sending scheduling messages on behalf of the owner of the calendar
collection.
Organizer scheduling object resource: A scheduling object resource
owned by an Organizer.
Attendee scheduling object resource: A scheduling object resource
owned by an Attendee.
Automatic scheduling transaction: Add, change or remove operations
on a scheduling object resource for which the server will deliver
scheduling messages to other Calendar Users.
Daboo & Desruisseaux Expires March 10, 2012 [Page 6]
Internet-Draft CalDAV Scheduling Extensions September 2011
Scheduling message: A calendar object that describes a scheduling
transaction such as schedule, reschedule, reply, or cancel.
Scheduling Outbox collection: A resource at which busy time
information requests are targeted.
Scheduling Inbox collection: A collection in which incoming
scheduling messages are delivered.
1.2. Approach
iTIP [RFC5546] outlines a model where Calendar Users exchange
scheduling messages with one another. Often times, clients are made
responsible for generating and sending scheduling messages as well as
processing incoming scheduling messages. This approach yields a
number of problems, including:
o For most updates to a calendar component, clients are responsible
for sending appropriate scheduling messages to the Organizer or
the Attendees.
o The handling of incoming scheduling messages and the updates to
calendars impacted by those messages only occurs when clients are
active.
o Due to the update latency, it is possible for calendars of
different Calendar Users to reflect different, inaccurate states.
This specification uses an alternative approach where the server is
made responsible for sending scheduling messages and processing
incoming scheduling messages. This approach frees the clients from
the submission and processing of scheduling messages and ensures
better consistency of calendar data across users' calendars. The
operation of creating, modifying or deleting a calendar component in
a calendar is enough to trigger the server to deliver the necessary
scheduling messages to the appropriate Calendar Users.
1.3. Limitations
While the scheduling features described in this specification are
based on iTIP [RFC5546], some of its more advanced features have
deliberately been left out in order to keep this specification
simple. In particular, the following iTIP [RFC5546] features are not
covered: publishing, countering, delegating, refreshing and
forwarding calendar components, as well as replacing the Organizer of
a calendar component.
The goal of this specification is to provide the essential scheduling
Daboo & Desruisseaux Expires March 10, 2012 [Page 7]
Internet-Draft CalDAV Scheduling Extensions September 2011
features needed. It is expected that future extensions will be
developed to address the more advanced features.
1.4. Notational Conventions
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in [RFC2119].
The Augmented BNF (ABNF) syntax used by this document to specify the
format definition of new iCalendar elements is defined in [RFC5234].
The Augmented BNF (ABNF) syntax used by this document to specify the
format definition of new message header fields to be used with the
HTTP/1.1 protocol is described in Section 2.1 of [RFC2616]. Since
this Augmented BNF uses the basic production rules provided in
Section 2.2 of [RFC2616], these rules apply to this document as well.
The term "protected" is used in the Conformance field of WebDAV
property definitions as defined in Section 15 of [RFC4918].
1.5. XML Namespaces and Processing
This document uses XML DTD fragments ([W3C.REC-xml-20081126], Section
3.2) as a purely notational convention. WebDAV request and response
bodies cannot be validated by a DTD due to the specific extensibility
rules defined in Section 17 of [RFC4918] and due to the fact that all
XML elements defined by that specification use the XML namespace name
"DAV:". In particular:
1. element names use the "DAV:" namespace,
2. element ordering is irrelevant unless explicitly stated,
3. extension elements (elements not already defined as valid child
elements) may be added anywhere, except when explicitly stated
otherwise,
4. extension attributes (attributes not already defined as valid for
this element) may be added anywhere, except when explicitly
stated otherwise.
The XML elements specified in this document are defined in the
"urn:ietf:params:xml:ns:caldav" XML namespace registered by CalDAV
[RFC4791].
When XML element types in the namespaces "DAV:" and
"urn:ietf:params:xml:ns:caldav" are referenced in this document
Daboo & Desruisseaux Expires March 10, 2012 [Page 8]
Internet-Draft CalDAV Scheduling Extensions September 2011
outside of the context of an XML fragment, the strings "DAV:" and
"CALDAV:" will be prefixed to the element types, respectively.
This document inherits, and sometimes extends, DTD productions from
Section 14 of [RFC4918].
Also note that some CalDAV XML element names are identical to WebDAV
XML element names, though their namespace differs. Care must be
taken not to confuse the two sets of names.
Daboo & Desruisseaux Expires March 10, 2012 [Page 9]
Internet-Draft CalDAV Scheduling Extensions September 2011
2. Scheduling Process
The process of scheduling an event between different parties often
involves a series of steps with different actors playing particular
roles during the whole process. Typically there is an event
"Organizer" whose role is to schedule an event between one or more
"Attendees", and this is done by sending out invitations and handling
responses from each Attendee.
This process can typically be broken down into two phases.
In the first phase, the Organizer will query the busy time
information of each Attendee to determine the most appropriate time
for the event. This request is sometimes called a "freebusy" lookup.
In the second phase, the Organizer sends out invitations to each
Attendee using the time previously determined from the freebusy
lookup. There then follows exchanges between Organizer and Attendees
regarding the invitation. Some Attendees may choose to attend at the
time proposed by the Organizer, others may decline to attend. The
Organizer needs to process each of the replies from the Attendees and
take appropriate action to confirm the event, reschedule it or
perhaps cancel it.
The user expectation as to how a calendaring and scheduling system
should respond in each of these two phases is somewhat different. In
the case of a freebusy lookup, users expect to get back results
immediately so that they can then move on to the invitation phase as
quickly as possible. In the case of invitations, it is expected that
each Attendee will reply with their participation status in their own
time, so delays in receiving replies are anticipated. Thus
calendaring and scheduling systems should treat these two operational
phases in different ways to accommodate the user expectations, which
is what this specification does.
While the scenario described above only covers the case of scheduling
events between Calendar Users, and requesting busy time information,
this specification also provides support for the scheduling of to-dos
between Calendar Users. For the majority of the following
discussion, scheduling of events and freebusy lookups will be
discussed, as these are the more common operations.
Daboo & Desruisseaux Expires March 10, 2012 [Page 10]
Internet-Draft CalDAV Scheduling Extensions September 2011
3. Scheduling Support
A server that supports the features described in this document MUST
include "calendar-auto-schedule" as a field in the DAV response
header from an OPTIONS request on any resource that supports any
scheduling actions, properties, privileges or methods.
To advertise support for the CalDAV "calendar-auto-schedule" feature
a server is REQUIRED to support and advertise support for the CalDAV
"calendar-access" [RFC4791] feature.
3.1. Example OPTIONS Request
In this example, the OPTIONS response indicates that the server
supports the "calendar-access" and "calendar-auto-schedule" features
and that the resource "/home/cyrus/calendars/inbox/" supports the
scheduling actions, properties, privileges and methods defined in
this specification.
>> Request <<
OPTIONS /home/cyrus/calendars/inbox/ HTTP/1.1
Host: cal.example.com
>> Response <<
HTTP/1.1 204 No Content
Date: Thu, 31 Mar 2011 09:00:00 GMT
Allow: OPTIONS, GET, HEAD, DELETE, TRACE, PROPFIND
Allow: PROPPATCH, LOCK, UNLOCK, REPORT, ACL
DAV: 1, 2, 3, access-control
DAV: calendar-access, calendar-auto-schedule
Daboo & Desruisseaux Expires March 10, 2012 [Page 11]
Internet-Draft CalDAV Scheduling Extensions September 2011
4. Scheduling Collections
This specification introduces new collection resource types that are
used to manage scheduling object resources, and scheduling
privileges, as well as provide scheduling functionality. It is the
server's responsibility to create these collection resources, and
clients have no way to create or delete them.
4.1. Scheduling Outbox Collection
A scheduling Outbox collection is used as the target for busy time
information requests, and to manage privileges that apply to outgoing
scheduling requests.
A scheduling Outbox collection MUST report the DAV:collection and
CALDAV:schedule-outbox XML elements in the value of the DAV:
resourcetype property. The element type declaration for CALDAV:
schedule-outbox is:
<!ELEMENT schedule-outbox EMPTY>
Example:
<D:resourcetype xmlns:D="DAV:">
<D:collection/>
<C:schedule-outbox xmlns:C="urn:ietf:params:xml:ns:caldav"/>
</D:resourcetype>
New WebDAV ACL [RFC3744] privileges can be set on the scheduling
Outbox collection to control who is allowed to send scheduling
messages on behalf of the Calendar User associated with the
scheduling Outbox collection. See Section 13.1 for more details.
A scheduling Outbox collection MUST NOT be a child (at any depth) of
a calendar collection resource.
The following WebDAV properties specified in CalDAV "calendar-access"
[RFC4791] MAY also be defined on scheduling Outbox collections:
CALDAV:supported-calendar-component-set - when present this
indicates the allowed calendar component types for scheduling
messages submitted to the scheduling Outbox collection with the
POST method.
CALDAV:supported-calendar-data - when present this indicates the
allowed media types for scheduling messages submitted to the
scheduling Outbox collection with the POST method.
Daboo & Desruisseaux Expires March 10, 2012 [Page 12]
Internet-Draft CalDAV Scheduling Extensions September 2011
CALDAV:max-resource-size - when present this indicates the maximum
size in octets of a resource that the server is willing to accept
for scheduling messages submitted to the scheduling Outbox
collection with the POST method.
CALDAV:min-date-time - when present this indicates the earliest
date and time (in UTC) that the server is willing to accept for
any DATE or DATE-TIME value in scheduling messages submitted to
the scheduling Outbox collection with the POST method.
CALDAV:max-date-time - when present this indicates the latest date
and time (in UTC) that the server is willing to accept for any
DATE or DATE-TIME value in scheduling messages submitted to the
scheduling Outbox collection with the POST method.
CALDAV:max-attendees-per-instance - when present this indicates
the maximum number of ATTENDEE properties in any instance of
scheduling messages submitted to the scheduling Outbox collection
with the POST method. Specifically, this limits the total number
of Attendees whose freebusy information can be queried in a single
request.
The use of child resources in a scheduling Outbox collection is
reserved for future revisions or extensions of this specification.
4.2. Scheduling Inbox Collection
A scheduling Inbox collection contains copies of incoming scheduling
messages. These may be requests sent by an Organizer, or replies
sent by an Attendee in response to a request. The scheduling Inbox
collection is also used to manage scheduling privileges.
A scheduling Inbox collection MUST report the DAV:collection and
CALDAV:schedule-inbox XML elements in the value of the DAV:
resourcetype property. The element type declaration for CALDAV:
schedule-inbox is:
<!ELEMENT schedule-inbox EMPTY>
Example:
<D:resourcetype xmlns:D="DAV:">
<D:collection/>
<C:schedule-inbox xmlns:C="urn:ietf:params:xml:ns:caldav"/>
</D:resourcetype>
Scheduling Inbox collections MUST only contain calendar object
resources that obey the restrictions specified in iTIP [RFC5546].
Daboo & Desruisseaux Expires March 10, 2012 [Page 13]
Internet-Draft CalDAV Scheduling Extensions September 2011
Consequently, scheduling Inbox collections MUST NOT contain any types
of collection resources. Restrictions defined in Section 4.1 of
CalDAV "calendar-access" [RFC4791] on calendar object resources
contained in calendar collections (e.g., "UID" uniqueness) do not
apply to calendar object resources contained in a scheduling Inbox
collection. Thus, multiple calendar object resources contained in a
scheduling Inbox collection can have the same "UID" property value
(i.e., multiple scheduling messages for the same calendar component).
New WebDAV ACL [RFC3744] privileges can be set on the scheduling
Inbox collection to control from whom the Calendar User associated
with the scheduling Inbox collection will accept scheduling messages
from. See Section 13.1 for more details.
A scheduling Inbox collection MUST NOT be a child (at any depth) of a
calendar collection resource.
The following WebDAV properties specified in CalDAV "calendar-access"
[RFC4791] MAY also be defined on scheduling Inbox collections:
CALDAV:calendar-timezone - when present this contains a time zone
that the server can use when calendar date-time operations are
carried out, for example when a time-range CALDAV:calendar-query
REPORT is targeted at a scheduling Inbox collection.
CALDAV:supported-calendar-component-set - when present this
indicates the allowed calendar component types for scheduling
messages delivered to the scheduling Inbox collection.
CALDAV:supported-calendar-data - when present this indicates the
allowed media types for scheduling messages delivered to the
scheduling Inbox collection.
CALDAV:max-resource-size - when present this indicates the maximum
size in octets of a resource that the server is willing to accept
for scheduling messages delivered to the scheduling Inbox
collection.
CALDAV:min-date-time - when present this indicates the earliest
date and time (in UTC) that the server is willing to accept for
any DATE or DATE-TIME value in scheduling messages delivered to
the scheduling Inbox collection.
CALDAV:max-date-time - when present this indicates the latest date
and time (in UTC) that the server is willing to accept for any
DATE or DATE-TIME value in scheduling messages delivered to the
scheduling Inbox collection.
Daboo & Desruisseaux Expires March 10, 2012 [Page 14]
Internet-Draft CalDAV Scheduling Extensions September 2011
CALDAV:max-instances - when present this indicates the maximum
number of recurrence instances in scheduling messages delivered to
the scheduling Inbox collection.
CALDAV:max-attendees-per-instance - when present this indicates
the maximum number of ATTENDEE properties in any instance of
scheduling messages delivered to the scheduling Inbox collection.
4.3. Calendaring Reports Extensions
This specification extends the CALDAV:calendar-query and CALDAV:
calendar-multiget REPORTs to return results for calendar object
resources in scheduling Inbox collections.
When a CALDAV:calendar-query REPORT includes a time-range query and
targets a scheduling Inbox collection, if any calendar object
resources contain "VEVENT" calendar components that do not include a
"DTSTART" iCalendar property (as allowed by iTIP [RFC5546]) then such
components MUST always match the time-range query test.
Note that the CALDAV:free-busy-query REPORT is not supported on
scheduling Inbox collections.
Daboo & Desruisseaux Expires March 10, 2012 [Page 15]
Internet-Draft CalDAV Scheduling Extensions September 2011
5. Scheduling Transactions
When a calendar object resource is created, modified or removed from
a calendar collection, the server examines the calendar data and
checks to see whether the data represents a scheduling object
resource. If it does, the server will automatically attempt to
deliver a scheduling message to the appropriate Calendar Users.
Several types of scheduling operations can occur in this case,
equivalent to iTIP "REQUEST", "REPLY", "CANCEL", and "ADD"
operations.
5.1. Identifying Scheduling Object Resources
Calendar object resources on which the server performs automatic
scheduling transactions are referred to as scheduling object
resources. There are two types of scheduling object resources:
organizer scheduling object resources, and attendee scheduling object
resources.
A calendar object resource is considered to be a valid organizer
scheduling object resource if the "ORGANIZER" iCalendar property is
present and set in all the calendar components to a value that
matches one of the calendar user addresses of the owner of the
calendar collection.
A calendar object resource is considered to be a valid attendee
scheduling object resource if the "ORGANIZER" iCalendar property is
present and set in all the calendar components to the same value and
doesn't match one of the calendar user addresses of the owner of the
calendar collection, and at least one of the "ATTENDEE" iCalendar
property values matches one of the calendar user addresses of the
owner of the calendar collection.
The creation of attendee scheduling object resources is typically
done by the server, with the resource being created in an appropriate
calendar collection (see Section 6.4).
5.2. Handling Scheduling Object Resources
The server's behavior when processing a scheduling object resource
depends on whether it is owned by the Organizer or an Attendee
specified in the calendar data.
5.2.1. Organizer Scheduling Object Resources
An Organizer can create, modify or remove a scheduling object
resource. The create, modify and remove behaviors for the server are
each described next, and the way these are invoked via HTTP requests
Daboo & Desruisseaux Expires March 10, 2012 [Page 16]
Internet-Draft CalDAV Scheduling Extensions September 2011
is described in Section 5.2.3.
The Organizer of a calendar component may also be an Attendee of that
calendar component. In such cases the server MUST NOT send a
scheduling message to the Attendee that matches the Organizer.
5.2.1.1. Create
When a scheduling object resource is created by the Organizer, the
server will inspect each "ATTENDEE" property to determine if a
scheduling message should be delivered to this Attendee according to
the value of the "SCHEDULE-AGENT" property parameter (see
Section 10.1) as described in the table below:
+------------------+-------------+
| SCHEDULE-AGENT | iTIP METHOD |
+==================+=============+
| SERVER (default) | REQUEST |
+------------------+-------------+
| CLIENT | -- |
+------------------+-------------+
| NONE | -- |
+------------------+-------------+
The attempt to deliver the scheduling message will either succeed or
fail. In all cases, the server MUST add a "SCHEDULE-STATUS"
iCalendar property parameter (see Section 10.3) to the "ATTENDEE"
iCalendar property in the scheduling object resource being created,
and set its value as described in Section 9.2. This will result in
the created calendar object resource differing from the calendar data
sent in the HTTP request. As a result clients MAY reload the
calendar data from the server in order to update to the new server
generated state information. Servers MUST NOT set the "SCHEDULE-
STATUS" property parameter on the "ATTENDEE" property of Attendees
for which it did not attempt to deliver a scheduling message.
Restrictions:
1. The server SHOULD reject any attempt to set the "PARTSTAT"
iCalendar property parameter value of the "ATTENDEE" iCalendar
property of other users in the calendar object resource to a
value other than "NEEDS-ACTION" if the "SCHEDULE-AGENT" property
parameter value is not present or set to the value "SERVER".
2. The server MAY reject attempts to create a scheduling object
resource that specifies a "UID" property value already specified
in a scheduling object resource contained in another calendar
collection of the Organizer.
Daboo & Desruisseaux Expires March 10, 2012 [Page 17]
Internet-Draft CalDAV Scheduling Extensions September 2011
3. The server MUST take into account scheduling privileges as
described in Section 13.1 when handling the creation of a
scheduling object resource.
4. Restrictions on calendar object resources defined in Section 4.1
of [RFC4791] MUST also be enforced.
The server MUST return an error with the CALDAV:allowed-organizer-
scheduling-object-change precondition code (Section 5.2.4.3) when the
Organizer attempts to change the iCalendar data in a manner that is
forbidden.
5.2.1.2. Modify
When a scheduling object resource is modified by the Organizer, the
server will inspect each "ATTENDEE" property in the new calendar data
to determine which ones have the "SCHEDULE-AGENT" iCalendar property
parameter. It will then need to compare this with the "ATTENDEE"
properties in the existing calendar object resource that is being
modified.
For each Attendee in the old and new calendar data on a per-instance
basis, and taking into account the addition or removal of Attendees,
the server will determine whether to deliver a scheduling message to
the Attendee. The following table determines whether the server
needs to deliver a scheduling message, and if so which iTIP
scheduling method to use. The values "SERVER", "CLIENT", and "NONE"
in the top and left titles of the table refer to the "SCHEDULE-AGENT"
parameter value of the "ATTENDEE" property, and the values "<Absent>"
and "<Removed>" are used to cover the cases where the "ATTENDEE"
property is not present (Old) or is being removed (New).
Daboo & Desruisseaux Expires March 10, 2012 [Page 18]
Internet-Draft CalDAV Scheduling Extensions September 2011
+---------------+-----------------------------------------------+
| | New |
| ATTENDEE +-----------+-----------+-----------+-----------+
| | <Removed> | SERVER | CLIENT | NONE |
| | | (default) | | |
+===+===========+===========+===========+===========+===========+
| | <Absent> | -- | REQUEST / | -- | -- |
| | | | ADD | | |
| +-----------+-----------+-----------+-----------+-----------+
| | SERVER | CANCEL | REQUEST | CANCEL | CANCEL |
| O | (default) | | | | |
| l +-----------+-----------+-----------+-----------+-----------+
| d | CLIENT | -- | REQUEST / | -- | -- |
| | | | ADD | | |
| +-----------+-----------+-----------+-----------+-----------+
| | NONE | -- | REQUEST / | -- | -- |
| | | | ADD | | |
+---+-----------+-----------+-----------+-----------+-----------+
The attempt to deliver the scheduling message will either succeed or
fail. In all cases, the server MUST add a "SCHEDULE-STATUS"
iCalendar property parameter to the "ATTENDEE" iCalendar property in
the scheduling object resource being modified, and set its value as
described in Section 9.2. This will result in the created calendar
object resource differing from the calendar data sent in the HTTP
request. As a result clients MAY reload the calendar data from the
server in order to update to the new server generated state
information.
Restrictions:
1. The server MAY reject any attempt to set the "PARTSTAT" iCalendar
property parameter value of the "ATTENDEE" iCalendar property of
other users in the calendar object resource to a value other than
"NEEDS-ACTION" if the "SCHEDULE-AGENT" property parameter value
is not present or set to the value "SERVER".
2. The server MUST take into account scheduling privileges as
described in Section 13.1 when handling the modification of a
scheduling object resource.
3. Restrictions on calendar object resources defined in Section 4.1
of [RFC4791] MUST also be enforced.
The server MUST return an error with the CALDAV:allowed-organizer-
scheduling-object-change precondition code (Section 5.2.4.3) when the
Organizer attempts to change the iCalendar data in a manner that is
forbidden.
Daboo & Desruisseaux Expires March 10, 2012 [Page 19]
Internet-Draft CalDAV Scheduling Extensions September 2011
5.2.1.3. Remove
When a scheduling object resource is removed by the Organizer, the
server will inspect each "ATTENDEE" property in the scheduling object
resource being removed to determine which ones have the "SCHEDULE-
AGENT" iCalendar property parameter.
For each Attendee the server will determine whether to attempt to
deliver a scheduling message into the Attendee's scheduling Inbox
collection, based on the table below:
+------------------+-------------+
| SCHEDULE-AGENT | iTIP METHOD |
+==================+=============+
| SERVER (default) | CANCEL |
+------------------+-------------+
| CLIENT | -- |
+------------------+-------------+
| NONE | -- |
+------------------+-------------+
Restrictions:
1. The server MUST take into account scheduling privileges as
described in Section 13.1 when handling the deletion of a
scheduling object resource.
5.2.2. Attendee Scheduling Object Resources
An Attendee can create, modify or remove a scheduling object resource
by issuing HTTP requests with an appropriate method. The create,
modify and remove behaviors for the server are each described next,
and the way these are invoked via HTTP requests is described in
Section 5.2.3.
5.2.2.1. Allowed Attendee Changes
Attendees are allowed to make some changes to a scheduling object
resource, though key properties such as start time, end time,
location, and summary are typically under the control of the
Organizer.
The server MUST allow Attendees to:
1. change their own "PARTSTAT" iCalendar property parameter value.
2. add, modify or remove any "TRANSP" iCalendar properties.
Daboo & Desruisseaux Expires March 10, 2012 [Page 20]
Internet-Draft CalDAV Scheduling Extensions September 2011
3. add, modify or remove any "PERCENT-COMPLETE" iCalendar
properties.
4. add, modify or remove any "COMPLETED" iCalendar properties.
5. add, modify or remove any "VALARM" iCalendar components.
6. add, modify or remove the "CALSCALE" iCalendar property within
the top-level "VCALENDAR" component.
7. modify the "PRODID" iCalendar property within the top-level
"VCALENDAR" component.
8. add "EXDATE" iCalendar properties and possibly remove components
for overridden recurrence instances.
9. add, modify or remove any "CREATED", "DTSTAMP" and "LAST-
MODIFIED" iCalendar properties.
10. add, modify or remove "SCHEDULE-STATUS" iCalendar property
parameters on "ATTENDEE" properties that have a "SCHEDULE-AGENT"
parameter set to "CLIENT".
11. add new components to represent overridden recurrence instances,
provided the only changes to the recurrence instance follow the
rules above.
The server MUST return an error with the CALDAV:allowed-attendee-
scheduling-object-change precondition code (Section 5.2.4.4) when the
Attendee attempts to change the iCalendar data in a manner forbidden
by the server.
5.2.2.2. Create
Typically an Attendee does not create scheduling object resources, as
scheduling messages delivered to them on the server are automatically
processed by the server and placed on one of their calendars (see
Section 6). However, in some cases a scheduling message may get
delivered directly to the client, and the Attendee may wish to store
that on the server. In that case the client creates a scheduling
object resource in a suitable calendar belonging to the Attendee. It
can then set the "SCHEDULE-AGENT" iCalendar property parameter on all
"ORGANIZER" iCalendar properties in the resource to determine how the
server treats the resource. The value of the "SCHEDULE-AGENT"
iCalendar property parameter on all "ORGANIZER" iCalendar properties
MUST be the same.
Daboo & Desruisseaux Expires March 10, 2012 [Page 21]
Internet-Draft CalDAV Scheduling Extensions September 2011
+----------------+--------------------------------------------------+
| SCHEDULE-AGENT | Action |
+----------------+--------------------------------------------------+
| SERVER | The server will attempt to process changes to |
| (default) | the resource using the normal rules for attendee |
| | scheduling object resources. |
| | |
| CLIENT | The server does no special processing of the |
| | resource. The client is assumed to be handling |
| | Attendee replies etc. |
| | |
| NONE | The server does no special processing of the |
| | resource. |
+----------------+--------------------------------------------------+
In some cases a server may not be able to process an Attendee
scheduling object resource that originated from another system (i.e.,
where the server is unable to deliver scheduling messages to the
Organizer). In such cases the server MUST add a "SCHEDULE-STATUS"
iCalendar property parameter to all "ORGANIZER" iCalendar properties
in the resource with a suitable value indicating a error.
5.2.2.3. Modify
When a scheduling object resource is modified by an Attendee, the
server behavior depends on the value of the "SCHEDULE-AGENT"
iCalendar property parameter on the "ORGANIZER" iCalendar properties:
+----------------+--------------------------------------------------+
| SCHEDULE-AGENT | Action |
+----------------+--------------------------------------------------+
| SERVER | The server will attempt to process the removal |
| (default) | using the behavior listed below. |
| | |
| CLIENT | The server does no special processing of the |
| | resource. The client is assumed to be handling |
| | any Attendee replies etc. |
| | |
| NONE | The server does no special processing of the |
| | resource. |
+----------------+--------------------------------------------------+
The server will inspect the changes by comparing the new scheduling
object resource with the existing scheduling object resource.
If the Attendee changes one or more "PARTSTAT" iCalendar property
values on any component, or adds an overridden component with a
changed "PARTSTAT" property, then the server MUST deliver an iTIP
Daboo & Desruisseaux Expires March 10, 2012 [Page 22]
Internet-Draft CalDAV Scheduling Extensions September 2011
"REPLY" scheduling message to the Organizer to indicate the new
participation status of the Attendee.
If the Attendee adds an "EXDATE" property value to effectively remove
a recurrence instance, the server MUST deliver an iTIP "REPLY"
scheduling message to the Organizer to indicate that the Attendee has
declined the instance (i.e., the Attendee's "PARTSTAT" iCalendar
property parameter value is set to "DECLINED").
The attempt to deliver the scheduling message will either succeed or
fail. In all cases, the server MUST add a "SCHEDULE-STATUS"
iCalendar property parameter to the "ORGANIZER" iCalendar property in
the scheduling object resource being created, and set its value as
described in Section 9.2. This will result in the created calendar