diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/akonadi-google.kdev4 akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/akonadi-google.kdev4 --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/akonadi-google.kdev4 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/akonadi-google.kdev4 1970-01-01 00:00:00.000000000 +0000 @@ -1,3 +0,0 @@ -[Project] -Manager=KDevCMakeManager -Name=akonadi-google diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/calendareditor.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/calendareditor.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/calendareditor.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/calendareditor.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,101 +0,0 @@ -/* - Akonadi Google - Calendar Resource - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#include "calendareditor.h" -#include "ui_calendar_editor.h" - -#include - -#include -#include -#include - -using namespace KGoogle::Objects; - -CalendarEditor::CalendarEditor(Calendar *calendar) : - QDialog(), - m_calendar(calendar) -{ - m_ui = new Ui::CalendarEditor(); - m_ui->setupUi(this); - - initTimezones(); - - if (calendar) { - initWidgets(); - } else { - int i = m_ui->timezoneCombo->findText(KSystemTimeZones::local().name(), Qt::MatchContains); - if (i > -1) { - m_ui->timezoneCombo->setCurrentIndex(i); - } - } - - connect(m_ui->buttons, SIGNAL(accepted()), - this, SLOT(accepted())); -} - -CalendarEditor::~CalendarEditor() -{ - delete m_ui; -} - -void CalendarEditor::accepted() -{ - if (!m_calendar) { - m_calendar = new KGoogle::Objects::Calendar(); - } - - m_calendar->setTitle(m_ui->nameEdit->text()); - m_calendar->setDetails(m_ui->descriptionEdit->toPlainText()); - m_calendar->setLocation(m_ui->locationEdit->text()); - m_calendar->setTimezone(m_ui->timezoneCombo->currentText()); - - Q_EMIT accepted(m_calendar); -} - - -void CalendarEditor::initTimezones() -{ - - Q_FOREACH(const KTimeZone tz, KSystemTimeZones::zones()) { - QIcon icon; - - QString flag = KStandardDirs::locate("locale", QString("l10n/%1/flag.png").arg(tz.countryCode().toLower())); - - if (QFile::exists(flag)) { - icon = QIcon(flag); - } - - m_ui->timezoneCombo->addItem(icon, tz.name()); - } -} - -void CalendarEditor::initWidgets() -{ - - m_ui->nameEdit->setText(m_calendar->title()); - m_ui->descriptionEdit->setText(m_calendar->details()); - m_ui->locationEdit->setText(m_calendar->location()); - - int tzIndex = m_ui->timezoneCombo->findText(m_calendar->timezone(), Qt::MatchContains); - - if (tzIndex > -1) { - m_ui->timezoneCombo->setCurrentIndex(tzIndex); - } -} diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/calendareditor.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/calendareditor.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/calendareditor.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/calendareditor.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,59 +0,0 @@ -/* - Akonadi Google - Calendar Resource - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#ifndef CALENDAREDITOR_H -#define CALENDAREDITOR_H - -#include - -#include - -namespace Ui -{ -class CalendarEditor; -} - -using namespace KGoogle::Objects; - -class CalendarEditor: public QDialog -{ - Q_OBJECT - - public: - explicit CalendarEditor(Calendar *calendar = 0); - - virtual ~CalendarEditor(); - - Q_SIGNALS: - void accepted(KGoogle::Objects::Calendar *calendar); - - private Q_SLOTS: - void accepted(); - - private: - void initTimezones(); - void initColors(); - void initWidgets(); - - Calendar *m_calendar; - Ui::CalendarEditor *m_ui; -}; - -#endif // CALENDAREDITOR_H - diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/calendarresource.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/calendarresource.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/calendarresource.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/calendarresource.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,708 +0,0 @@ -/* - Akonadi Google - Calendar Resource - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "calendarresource.h" -#include "defaultreminderattribute.h" -#include "settings.h" -#include "settingsdialog.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WITH_KCAL -#include -using namespace KCal; -#define EVENT_MIMETYPE "application/x-vnd.akonadi.calendar.event" -#define TODO_MIMETYPE "application/x-vnd.akonadi.calendar.todo" -#else -#include -#include -using namespace KCalCore; -#define EVENT_MIMETYPE Event::eventMimeType() -#define TODO_MIMETYPE Todo::todoMimeType() -#endif - - -using namespace Akonadi; -using namespace KGoogle; - -CalendarResource::CalendarResource(const QString &id): - ResourceBase(id), - m_account(0), - m_fetchedCalendars(false), - m_fetchedTaskLists(false) -{ - qRegisterMetaType< KGoogle::Services::Calendar >("Calendar"); - qRegisterMetaType< KGoogle::Services::Tasks >("Tasks"); - AttributeFactory::registerAttribute< DefaultReminderAttribute >(); - - Auth *auth = Auth::instance(); - auth->init("Akonadi Google", Settings::self()->clientId(), Settings::self()->clientSecret()); - - setNeedsNetwork(true); - setOnline(true); - - m_gam = new AccessManager(); - connect(m_gam, SIGNAL(error(KGoogle::Error, QString)), - this, SLOT(error(KGoogle::Error, QString))); - connect(m_gam, SIGNAL(replyReceived(KGoogle::Reply*)), - this, SLOT(replyReceived(KGoogle::Reply*))); - - connect(this, SIGNAL(abortRequested()), - this, SLOT(slotAbortRequested())); - connect(this, SIGNAL(reloadConfiguration()), - this, SLOT(reloadConfig())); - - changeRecorder()->itemFetchScope().fetchFullPayload(true); - changeRecorder()->itemFetchScope().setAncestorRetrieval(ItemFetchScope::All); - changeRecorder()->fetchCollection(true); - changeRecorder()->collectionFetchScope().setAncestorRetrieval(CollectionFetchScope::All); - - if (!Settings::self()->account().isEmpty()) { - if (!getAccount().isNull()) { - synchronize(); - } - } -} - -CalendarResource::~CalendarResource() -{ - delete m_gam; -} - -void CalendarResource::aboutToQuit() -{ - cancelCurrentFetchJobs(); - slotAbortRequested(); -} - -void CalendarResource::abort() -{ - cancelTask(i18n("Aborted")); -} - -void CalendarResource::slotAbortRequested() -{ - abort(); -} - -void CalendarResource::cancelCurrentFetchJobs() -{ - Q_FOREACH(KJob *job, m_jobList) { - job->disconnect(this); //We don't want to handle any response - job->kill(); - } - m_jobList.clear(); -} - -void CalendarResource::error(const KGoogle::Error errCode, const QString &msg) -{ - cancelTask(msg); - - if ((errCode == AuthError) || (errCode == BackendNotReady)) { - status(Broken, msg); - } -} - -void CalendarResource::configure(WId windowId) -{ - SettingsDialog *settingsDialog = new SettingsDialog(windowId); - - if (settingsDialog->exec() == KDialog::Accepted) { - Q_EMIT configurationDialogAccepted(); - - delete settingsDialog; - - if (!getAccount().isNull()) { - synchronize(); - } - - } else { - Q_EMIT configurationDialogRejected(); - - delete settingsDialog; - } -} - -void CalendarResource::reloadConfig() -{ - if (getAccount().isNull()) { - return; - } - - synchronize(); -} - -Account::Ptr CalendarResource::getAccount() -{ - if (!m_account.isNull()) - return m_account; - - Auth *auth = Auth::instance(); - try { - m_account = auth->getAccount(Settings::self()->account()); - } catch (KGoogle::Exception::BaseException &e) { - Q_EMIT status(Broken, e.what()); - return Account::Ptr(); - } - - return m_account; -} - -void CalendarResource::addFetchJob(KJob* job) -{ - connect(job, SIGNAL(finished(KJob*)), this, SLOT(jobFinished(KJob*))); - m_jobList.append(job); -} - -void CalendarResource::retrieveItems(const Akonadi::Collection& collection) -{ - /* Do not initiate item-retrieval for the root collection as this - * collection is only used to authenticate agains google and to hold - * all the calendars associated with this account. There are no items - * to be fetched from this collection! */ - if (collection.parentCollection() != Akonadi::Collection::root()) { - ItemFetchJob *fetchJob = new ItemFetchJob(collection, this); - connect(fetchJob, SIGNAL(finished(KJob*)), - this, SLOT(cachedItemsRetrieved(KJob*))); - connect(fetchJob, SIGNAL(finished(KJob*)), - fetchJob, SLOT(deleteLater())); - - addFetchJob(fetchJob); - fetchJob->fetchScope().fetchFullPayload(false); - fetchJob->setProperty("collection", qVariantFromValue(collection)); - fetchJob->start(); - - Q_EMIT percent(0); - } else { - itemsRetrievalDone(); - } -} - -void CalendarResource::cachedItemsRetrieved(KJob* job) -{ - QUrl url; - QString service; - QString lastSync; - - Collection collection = job->property("collection").value(); - - if (collection.contentMimeTypes().contains(EVENT_MIMETYPE)) { - - service = "Calendar"; - url = Services::Calendar::fetchEventsUrl(collection.remoteId()); - - } else if (collection.contentMimeTypes().contains(TODO_MIMETYPE)) { - - service = "Tasks"; - url = Services::Tasks::fetchAllTasksUrl(collection.remoteId()); - - } else { - - Q_EMIT cancelTask(i18n("Invalid collection")); - return; - - } - - lastSync = collection.remoteRevision(); - if (!lastSync.isEmpty()) { - KDateTime dt; - dt.setTime_t(lastSync.toInt()); - lastSync = AccessManager::dateToRFC3339String(dt); - - url.addQueryItem("updatedMin", lastSync); - } - - url.addQueryItem("showDeleted", "true"); - - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return; - } - - FetchListJob *fetchJob = new FetchListJob(url, service, account->accountName()); - fetchJob->setProperty("collection", qVariantFromValue(collection)); - connect(fetchJob, SIGNAL(finished(KJob*)), - this, SLOT(itemsReceived(KJob*))); - connect(fetchJob, SIGNAL(percent(KJob*, ulong)), - this, SLOT(emitPercent(KJob*, ulong))); - - addFetchJob(fetchJob); - fetchJob->start(); -} - - -bool CalendarResource::retrieveItem(const Akonadi::Item& item, const QSet< QByteArray >& parts) -{ - Q_UNUSED(parts); - - QString service; - QUrl url; - - if (item.parentCollection().contentMimeTypes().contains(EVENT_MIMETYPE)) { - - service = "Calendar"; - url = Services::Calendar::fetchEventUrl(item.parentCollection().remoteId(), item.remoteId()); - - } else if (item.parentCollection().contentMimeTypes().contains(TODO_MIMETYPE)) { - - service = "Tasks"; - url = Services::Tasks::fetchTaskUrl(item.parentCollection().remoteId(), item.remoteId()); - - } - - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return true; - } - - Request *request = new Request(url, KGoogle::Request::Fetch, service, account); - request->setProperty("Item", QVariant::fromValue(item)); - m_gam->sendRequest(request); - - return true; -} - -void CalendarResource::retrieveCollections() -{ - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return; - } - - Akonadi::EntityDisplayAttribute *attr = new Akonadi::EntityDisplayAttribute(); - attr->setDisplayName(account->accountName()); - - Collection collection; - collection.setName(identifier()); - collection.setRemoteId(identifier()); - collection.setParentCollection(Akonadi::Collection::root()); - collection.setContentMimeTypes(QStringList() << Collection::mimeType() - << EVENT_MIMETYPE - << TODO_MIMETYPE); - collection.addAttribute(attr); - - /* For korganizer v4.4.11 a supercollection may not be read-only as korganizer obviously didn't check - * if there are subcollections which are not read-only. A read-only supercollection and all its sub- - * collections, regardless of their permissions, are not displayed by korganizer in all relevant dialogs. - * - * FIXME Allow only read-only access when merging to kdepim-runtime (see bug #295739) - */ - collection.setRights(Collection::CanCreateItem | Collection::CanChangeItem | Collection::CanDeleteItem); - - m_collections.clear(); - m_collections.append(collection); - - FetchListJob *fetchJob; - - fetchJob = new FetchListJob(Services::Calendar::fetchCalendarsUrl(), "Calendar", account->accountName()); - connect(fetchJob, SIGNAL(finished(KJob*)), - this, SLOT(calendarsReceived(KJob*))); - addFetchJob(fetchJob); - fetchJob->start(); - - fetchJob = new FetchListJob(Services::Tasks::fetchTaskListsUrl(), "Tasks", account->accountName()); - connect(fetchJob, SIGNAL(finished(KJob*)), - this, SLOT(taskListReceived(KJob*))); - addFetchJob(fetchJob); - fetchJob->start(); -} - -void CalendarResource::itemAdded(const Akonadi::Item& item, const Akonadi::Collection& collection) -{ - QString service; - QUrl url; - QByteArray data; - - if (collection.parentCollection() == Akonadi::Collection::root()) { - cancelTask(i18n("The top-level collection cannot contain any tasks or events")); - return; - } - - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return; - } - - if (item.mimeType() == EVENT_MIMETYPE) { - - EventPtr event = item.payload< EventPtr >(); - Objects::Event kevent(*event); - - service = "Calendar"; - url = Services::Calendar::createEventUrl(collection.remoteId()); - - Services::Calendar service; - kevent.setUid(""); - data = service.objectToJSON(static_cast< KGoogle::Object* >(&kevent)); - - } else if (item.mimeType() == TODO_MIMETYPE) { - - TodoPtr todo = item.payload< TodoPtr >(); - todo->setUid(""); - Objects::Task ktodo(*todo); - - service = "Tasks"; - url = Services::Tasks::createTaskUrl(collection.remoteId()); -#ifdef WITH_KCAL - if (!todo->relatedToUid().isEmpty()) - url.addQueryItem("parent", todo->relatedToUid()); -#else - if (!todo->relatedTo(Incidence::RelTypeParent).isEmpty()) - url.addQueryItem("parent", todo->relatedTo(Incidence::RelTypeParent)); -#endif - - Services::Tasks service; - data = service.objectToJSON(static_cast< KGoogle::Object* >(&ktodo)); - - } else { - cancelTask(i18n("Unknown payload type '%1'").arg(item.mimeType())); - return; - } - - Request *request = new Request(url, Request::Create, service, account); - request->setRequestData(data, "application/json"); - request->setProperty("Item", QVariant::fromValue(item)); - request->setProperty("Collection", QVariant::fromValue(collection)); - - m_gam->sendRequest(request); -} - -void CalendarResource::itemChanged(const Akonadi::Item& item, const QSet< QByteArray >& partIdentifiers) -{ - QUrl url; - QByteArray data; - - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return; - } - - if (item.mimeType() == EVENT_MIMETYPE) { - - EventPtr event = item.payload< EventPtr >(); - Objects::Event kevent(*event); - - /* Akonadi stores the event with it's own UID when it's created, - * but we need to make it same as remoteId, which is the event's - * original UID on Google. - * - * We could update the UID of newly created event after receiving it's - * proper remoteId (and thus Google's UID), but KOrganizer does not cope - * well with it (see bug #298518). */ - kevent.setUid(item.remoteId()); - - url = Services::Calendar::updateEventUrl(item.parentCollection().remoteId(), item.remoteId()); - - Services::Calendar service; - data = service.objectToJSON(static_cast< KGoogle::Object* >(&kevent)); - - Request *request = new Request(url, Request::Patch, "Calendar", account); - request->setRequestData(data, "application/json"); - request->setProperty("Item", QVariant::fromValue(item)); - - m_gam->sendRequest(request); - - } else if (item.mimeType() == TODO_MIMETYPE) { - - TodoPtr todo = item.payload< TodoPtr >(); - Objects::Task ktodo(*todo); - - /* See the comment above for explanation why we do this here */ - ktodo.setUid(item.remoteId()); - -#ifdef WITH_KCAL - QString parentUid = todo->relatedToUid(); -#else - QString parentUid = todo->relatedTo(KCalCore::Incidence::RelTypeParent); -#endif - QUrl moveUrl = Services::Tasks::moveTaskUrl(item.parentCollection().remoteId(), - todo->uid(), - parentUid); - Request *request = new Request(moveUrl, Request::Move, "Tasks", account); - request->setProperty("Item", QVariant::fromValue(item)); - - m_gam->sendRequest(request); - - } else { - cancelTask(i18n("Unknown payload type '%1'").arg(item.mimeType())); - return; - } - - Q_UNUSED(partIdentifiers); -} - -void CalendarResource::itemRemoved(const Akonadi::Item& item) -{ - QString service; - QUrl url; - - - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return; - } - - if (item.mimeType() == EVENT_MIMETYPE) { - - url = Services::Calendar::removeEventUrl(item.parentCollection().remoteId(), item.remoteId()); - Request *request = new Request(url, Request::Remove, "Calendar", account); - request->setProperty("Item", QVariant::fromValue(item)); - m_gam->sendRequest(request); - - } else if (item.mimeType() == TODO_MIMETYPE) { - - /* Google always automatically removes tasks with all their subtasks. In KOrganizer - * by default we only remove the item we are given. For this reason we have to first - * fetch all tasks, find all sub-tasks for the task being removed and detach them - * from the task. Only then the task can be safely removed. - */ - - ItemFetchJob *fetchJob = new ItemFetchJob(item.parentCollection()); - fetchJob->setAutoDelete(true); - fetchJob->fetchScope().fetchFullPayload(true); - fetchJob->setProperty("Item", qVariantFromValue(item)); - connect(fetchJob, SIGNAL(finished(KJob*)), - this, SLOT(removeTaskFetchJobFinished(KJob*))); - addFetchJob(fetchJob); - fetchJob->start(); - - } else { - cancelTask(i18n("Unknown payload type '%1'").arg(item.mimeType())); - return; - } - -} - -void CalendarResource::itemMoved(const Item& item, const Collection& collectionSource, const Collection& collectionDestination) -{ - QString service; - QUrl url; - - if (collectionDestination.parentCollection() == Akonadi::Collection::root()) { - cancelTask(i18n("The top-level collection cannot contain any tasks or events")); - return; - } - - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return; - } - - /* Moving tasks between task lists is not supported */ - if (item.mimeType() != EVENT_MIMETYPE) - return; - - url = Services::Calendar::moveEventUrl(collectionSource.remoteId(), collectionDestination.remoteId(), item.remoteId()); - Request *request = new Request(url, KGoogle::Request::Move, "Calendar", account); - request->setProperty("Item", qVariantFromValue(item)); - - m_gam->sendRequest(request); -} - - -void CalendarResource::replyReceived(KGoogle::Reply* reply) -{ - switch (reply->requestType()) { - case Request::FetchAll: - /* Handled by FetchListJob */ - break; - - case Request::Fetch: - itemReceived(reply); - break; - - case Request::Create: - itemCreated(reply); - break; - - case Request::Update: - case Request::Patch: - itemUpdated(reply); - break; - - case Request::Remove: - itemRemoved(reply); - break; - - case Request::Move: - itemMoved(reply); - break; - } -} - -void CalendarResource::itemMoved(Reply* reply) -{ - if (reply->serviceName() == "Calendar") { - - eventMoved(reply); - - } else if (reply->serviceName() == "Tasks") { - - taskDoUpdate(reply); - - } else { - - cancelTask(i18n("Received invalid reply")); - - } -} - -void CalendarResource::itemsReceived(KJob *job) -{ - FetchListJob *fetchJob = dynamic_cast< FetchListJob* >(job); - - if (fetchJob->service() == "Calendar") { - - eventsReceived(job); - - } else if (fetchJob->service() == "Tasks") { - - tasksReceived(job); - - } else { - - cancelTask(i18n("Received invalid reply")); - - } -} - -void CalendarResource::itemReceived(Reply* reply) -{ - if (reply->serviceName() == "Calendar") { - - eventReceived(reply); - - } else if (reply->serviceName() == "Tasks") { - - taskReceived(reply); - - } else { - - cancelTask(i18n("Received an invalid reply")); - - } - - delete reply; - -} - -void CalendarResource::itemCreated(Reply* reply) -{ - if (reply->serviceName() == "Calendar") { - - eventCreated(reply); - - } else if (reply->serviceName() == "Tasks") { - - taskCreated(reply); - - } else { - - cancelTask(i18n("Received an invalid reply")); - - } - - delete reply; - -} - -void CalendarResource::itemUpdated(Reply* reply) -{ - if (reply->serviceName() == "Calendar") { - - eventUpdated(reply); - - } else if (reply->serviceName() == "Tasks") { - - taskUpdated(reply); - - } else { - - cancelTask(i18n("Received an invalid reply")); - - } - - delete reply; - -} - -void CalendarResource::itemRemoved(Reply* reply) -{ - if (reply->serviceName() == "Calendar") { - - eventRemoved(reply); - - } else if (reply->serviceName() == "Tasks") { - - taskRemoved(reply); - - } else { - - cancelTask(i18n("Received an invalid reply")); - - } - - delete reply; -} - -void CalendarResource::emitPercent(KJob* job, ulong progress) -{ - Q_UNUSED(job); - - Q_EMIT percent(progress); -} - -void CalendarResource::jobFinished(KJob* job) -{ - m_jobList.removeOne(job); -} - -AKONADI_RESOURCE_MAIN(CalendarResource); diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/calendarresource.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/calendarresource.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/calendarresource.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/calendarresource.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,123 +0,0 @@ -/* - Akonadi Google - Calendar Resource - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#ifndef CALENDARRESOURCE_H -#define CALENDARRESOURCE_H - -#include -#include -#include -#include - -#include -#include - -namespace KGoogle -{ -class AccessManager; -class Account; -class Reply; -class Request; -} - -using namespace KGoogle; - -class CalendarResource : public Akonadi::ResourceBase, public Akonadi::AgentBase::ObserverV2 -{ - - Q_OBJECT - public: - CalendarResource(const QString &id); - ~CalendarResource(); - - void configure(WId windowId); - - - public Q_SLOTS: - void reloadConfig(); - void retrieveCollections(); - void retrieveItems(const Akonadi::Collection& collection); - bool retrieveItem(const Akonadi::Item& item, const QSet< QByteArray >& parts); - - void itemAdded(const Akonadi::Item& item, const Akonadi::Collection& collection); - void itemChanged(const Akonadi::Item& item, const QSet< QByteArray >& partIdentifiers); - void itemRemoved(const Akonadi::Item& item); - void itemMoved(const Akonadi::Item& item, const Akonadi::Collection& collectionSource, const Akonadi::Collection& collectionDestination); - - protected: - void aboutToQuit(); - - private Q_SLOTS: - void error(const KGoogle::Error, const QString&); - void slotAbortRequested(); - void cancelCurrentFetchJobs(); - - void cachedItemsRetrieved(KJob *job); - void replyReceived(KGoogle::Reply *reply); - - void itemsReceived(KJob *job); - void itemReceived(KGoogle::Reply *reply); - void itemCreated(KGoogle::Reply *reply); - void itemUpdated(KGoogle::Reply *reply); - void itemRemoved(KGoogle::Reply *reply); - void itemMoved(KGoogle::Reply *reply); - - void taskListReceived(KJob *job); - void calendarsReceived(KJob *job); - - /* The actual update of task */ - void taskDoUpdate(KGoogle::Reply *reply); - - void taskReceived(KGoogle::Reply *reply); - void tasksReceived(KJob *job); - void taskCreated(KGoogle::Reply *reply); - void taskUpdated(KGoogle::Reply *reply); - void taskRemoved(KGoogle::Reply *reply); - - void removeTaskFetchJobFinished(KJob *job); - void doRemoveTask(KJob *job); - - void eventReceived(KGoogle::Reply *reply); - void eventsReceived(KJob *job); - void eventCreated(KGoogle::Reply *reply); - void eventUpdated(KGoogle::Reply *reply); - void eventRemoved(KGoogle::Reply *reply); - void eventMoved(KGoogle::Reply *reply); - - void emitPercent(KJob* job, ulong percent); - - void jobFinished(KJob *job); - - private: - void abort(); - Account::Ptr getAccount(); - void addFetchJob(KJob *job); - - AccessManager *m_gam; - - Account::Ptr m_account; - - Akonadi::Collection::List m_collections; - QList m_jobList; - - bool m_fetchedCalendars; - bool m_fetchedTaskLists; -}; - -#endif // CALENDARRESOURCE_H diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/CMakeLists.txt akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/CMakeLists.txt --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/CMakeLists.txt 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,66 +0,0 @@ -project(googlecalendarresource) - -set(CALENDAR_RESOURCE_VERSION 0.3.1) - -cmake_minimum_required(VERSION 2.8) - -add_definitions(-DRESOURCE_VERSION="\\"${CALENDAR_RESOURCE_VERSION}\\"") -if (XSLTPROC_EXECUTABLE) - macro(kcfg_generate_dbus_interface _kcfg _name) - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml - COMMAND ${XSLTPROC_EXECUTABLE} --stringparam interfaceName ${_name} - ${KDEPIMLIBS_DATA_DIR}/akonadi-kde/kcfg2dbus.xsl - ${_kcfg} - > ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml - DEPENDS ${KDEPIMLIBS_DATA_DIR}/akonadi-kde/kcfg2dbus.xsl - ${_kcfg} - ) - endmacro(kcfg_generate_dbus_interface) -endif (XSLTPROC_EXECUTABLE) - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - -set(calendarresource_SRCS - calendareditor.cpp - calendarresource.cpp - defaultreminderattribute.cpp - resource_tasks.cpp - resource_events.cpp - settings.cpp - settingsdialog.cpp - tasklisteditor.cpp -) - -kde4_add_ui_files(calendarresource_SRCS - ui/settingsdialog.ui - ui/calendar_editor.ui - ui/tasklist_editor.ui) - -kde4_add_kcfg_files(calendarresource_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/settingsbase.kcfgc) -kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/settingsbase.kcfg org.kde.Akonadi.GoogleCalendar.Settings) -qt4_add_dbus_adaptor(calendarresource_SRCS - ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.GoogleCalendar.Settings.xml - ${CMAKE_CURRENT_SOURCE_DIR}/settings.h Settings) -kde4_add_executable(akonadi_googlecalendar_resource RUN_UNINSTALLED ${calendarresource_SRCS}) - -target_link_libraries(akonadi_googlecalendar_resource - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KCAL_LIBS} - ${KDEPIMLIBS_KCALCORE_LIBS} - ${KDEPIMLIBS_KMIME_LIBS} - ${QT_QTCORE_LIBRARY} - ${QT_QTGUI_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ${QT_QTNETWORK_LIBRARY} - ${KDE4_KDECORE_LIBS} - ${KDE4_KDEWEBKIT_LIBS} - ${QJSON_LIBRARIES} - kgoogle -) - -add_dependencies(akonadi_googlecalendar_resource libkgoogle) - - -install(TARGETS akonadi_googlecalendar_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) -install(FILES googlecalendarresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/defaultreminderattribute.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/defaultreminderattribute.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/defaultreminderattribute.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/defaultreminderattribute.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,117 +0,0 @@ -/* - - Copyright (C) 2012 Dan Vratil - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#include "defaultreminderattribute.h" - -#include - -#include -#include - -#include - -#ifdef WITH_KCAL -using namespace KCal; -#else -using namespace KCalCore; -#endif - -using namespace KGoogle::Objects; - -DefaultReminderAttribute::DefaultReminderAttribute (const Reminder::List& reminders): - m_reminders(reminders) -{ - -} - -Akonadi::Attribute* DefaultReminderAttribute::clone() const -{ - return new DefaultReminderAttribute(m_reminders); -} - -void DefaultReminderAttribute::deserialize (const QByteArray& data) -{ - QJson::Parser parser; - QVariantList list; - - list = parser.parse(data).toList(); - Q_FOREACH (const QVariant &l, list) { - QVariantMap reminder = l.toMap(); - - Reminder::Ptr rem(new Reminder); - if (reminder["type"].toString() == "display") { - rem->setType(Alarm::Display); - } else if (reminder["type"].toString() == "email") { - rem->setType(Alarm::Email); - } - - Duration offset(reminder["time"].toInt(), Duration::Seconds); - rem->setStartOffset(offset); - - m_reminders << rem; - } -} - -QByteArray DefaultReminderAttribute::serialized() const -{ - QVariantList list; - - Q_FOREACH (Reminder::Ptr rem, m_reminders) { - QVariantMap reminder; - - if (rem->type() == Alarm::Display) { - reminder["type"] = "display"; - } else if (rem->type() == Alarm::Email) { - reminder["type"] = "email"; - } - - reminder["time"] = rem->startOffset().asSeconds(); - - list << reminder; - } - - QJson::Serializer serializer; - return serializer.serialize(list); -} - -Alarm::List DefaultReminderAttribute::alarms(Incidence *incidence) const -{ - Alarm::List alarms; - - Q_FOREACH (const Reminder::Ptr &reminder, m_reminders) { - AlarmPtr alarm(new Alarm(incidence)); - - alarm->setType(reminder->type()); - alarm->setTime(incidence->dtStart()); - alarm->setStartOffset(reminder->startOffset()); - alarm->setEnabled(true); - - alarms << alarm; - } - - return alarms; -} - - -QByteArray DefaultReminderAttribute::type() const -{ - return "defaultReminders"; -} - diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/defaultreminderattribute.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/defaultreminderattribute.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/defaultreminderattribute.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/defaultreminderattribute.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* - Calendar Resource - Default Reminder Attribute - Copyright (C) 2012 Dan Vratil - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - -#ifndef DEFAULTREMINDERATTRIBUTE_H -#define DEFAULTREMINDERATTRIBUTE_H - -#include - -#include - -#ifdef WITH_KCAL -#include -#include -using namespace KCal; -#else -#include -#include -using namespace KCalCore; -#endif - -using namespace KGoogle; - -class DefaultReminderAttribute : public Akonadi::Attribute -{ - public: - DefaultReminderAttribute(const Objects::Reminder::List &reminders = Objects::Reminder::List()); - - Attribute* clone() const; - void deserialize (const QByteArray& data); - QByteArray serialized() const; - QByteArray type() const; - - Alarm::List alarms(Incidence *incidence) const; - - private: - Objects::Reminder::List m_reminders; -}; - -#endif // DEFAULTREMINDERATTRIBUTE_H diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/googlecalendarresource.desktop akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/googlecalendarresource.desktop --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/googlecalendarresource.desktop 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/googlecalendarresource.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,28 +0,0 @@ -[Desktop Entry] -Name=Google Calendars and Tasks -Name[da]=Google kalendere og opgaver -Name[de]=Google-Kalender und -Aufgaben -Name[es]=Calendarios y tareas de Google -Name[it]=Calendari e attività di Google -Name[nl]=Google agenda's en taken -Name[pt]=Calendários e Tarefas do Google -Name[pt_BR]=Calendários e tarefas do Google -Name[sv]=Google-kalendrar och uppgifter -Name[uk]=Календарі та записи завдань Google -Name[x-test]=xxGoogle Calendars and Tasksxx -Comment=Access your Google Calendars and Tasks from KDE -Comment[da]=Tilgå dine Google kalendere og opgaver fra KDE -Comment[de]=Zugriff von KDE auf Ihre Google-Kalender und -Aufgaben -Comment[es]=Acceda a sus calendarios y tareas de Google desde KDE -Comment[it]=Accedi ai tuoi calendari e alle tue attività di Google da KDE -Comment[nl]=Heb toegang tot uw Google agenda's en taken vanuit KDE -Comment[pt]=Aceda aos seus calendários e tarefas da Google a partir do KDE -Comment[pt_BR]=Acesse seus calendários e tarefas do Google a partir do KDE -Comment[sv]=Kom åt dina Google-kalendrar och uppgifter från KDE -Comment[uk]=Доступ до ваших календарів і записів завдань Google з KDE -Comment[x-test]=xxAccess your Google Calendars and Tasks from KDExx -Type=AkonadiResource -Exec=akonadi_googlecalendar_resource -X-Akonadi-MimeTypes=text/calendar,application/x-vnd.akonadi.calendar.event,application/x-vnd.akonadi.calendar.todo -X-Akonadi-Capabilities=Resource -X-Akonadi-Identifier=akonadi_googlecalendar_resource diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/resource_events.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/resource_events.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/resource_events.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/resource_events.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,297 +0,0 @@ -/* - * Akonadi Google - Calendar Resource - * Copyright (C) 2011 Dan Vratil - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include "calendarresource.h" -#include "defaultreminderattribute.h" -#include "settings.h" - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#ifdef WITH_KCAL -#include -#include -#else -#include -#include -#include -#endif - -using namespace Akonadi; -using namespace KGoogle; - -#ifdef WITH_KCAL -using namespace KCal; -#define EVENT_MIMETYPE "application/x-vnd.akonadi.calendar.event" -#else -using namespace KCalCore; -#define EVENT_MIMETYPE Event::eventMimeType() -#endif - -void CalendarResource::calendarsReceived(KJob *job) -{ - if (job->error()) { - Q_EMIT status(Broken, i18n("Failed to fetch calendars: %1").arg(job->errorString())); - cancelTask(); - return; - } - - FetchListJob *fetchJob = dynamic_cast< FetchListJob* >(job); - - QStringList calendars = Settings::self()->calendars(); - - QList< KGoogle::Object *> allData = fetchJob->items(); - Q_FOREACH(KGoogle::Object * replyData, allData) { - - Objects::Calendar *calendar = static_cast< Objects::Calendar* >(replyData); - - if (!calendars.contains(calendar->uid())) - continue; - - Collection collection; - collection.setRemoteId(calendar->uid()); - collection.setParentCollection(m_collections.first()); - collection.setContentMimeTypes(QStringList() << EVENT_MIMETYPE); - collection.setName(calendar->title()); - collection.setRights(Collection::CanCreateItem | Collection::CanChangeItem | Collection::CanDeleteItem); - - EntityDisplayAttribute *attr = new EntityDisplayAttribute; - attr->setDisplayName(calendar->title()); - attr->setIconName("text-calendar"); - collection.addAttribute(attr); - - DefaultReminderAttribute *reminderAttr = new DefaultReminderAttribute(calendar->defaultReminders()); - collection.addAttribute(reminderAttr); - - m_collections.append(collection); - - } - - m_fetchedCalendars = true; - - if (m_fetchedTaskLists && m_fetchedCalendars) { - collectionsRetrieved(m_collections); - m_collections.clear(); - - m_fetchedCalendars = false; - m_fetchedTaskLists = false; - } -} - -void CalendarResource::eventReceived(KGoogle::Reply *reply) -{ - if (reply->error() != OK) { - cancelTask(); - Q_EMIT status(Broken, i18n("Failed to fetch event: %1").arg(reply->errorString())); - return; - } - - QList< Object* > data = reply->replyData(); - if (data.length() != 1) { - kWarning() << "Server send " << data.length() << "items, which is not OK"; - cancelTask(i18n("Expected a single item, server sent %1 items.").arg(data.length())); - return; - } - - Item item = reply->request()->property("Item").value(); - - Objects::Event *event = static_cast< Objects::Event* >(data.first()); - - if (event->useDefaultReminders()) { - Collection collection = item.parentCollection(); - DefaultReminderAttribute *attr = dynamic_cast< DefaultReminderAttribute* >(collection.attribute("defaultReminders")); - if (attr) { - Alarm::List alarms = attr->alarms(event); - Q_FOREACH (AlarmPtr alarm, alarms) { - event->addAlarm(alarm); - } - } - } - - item.setRemoteId(event->uid()); - item.setRemoteRevision(event->etag()); - item.setMimeType(EVENT_MIMETYPE); - item.setPayload< EventPtr >(EventPtr(event)); - - if (event->deleted()) - itemsRetrievedIncremental(Item::List(), Item::List() << item); - else - itemRetrieved(item); -} - -void CalendarResource::eventsReceived(KJob *job) -{ - if (job->error()) { - cancelTask(i18n("Failed to fetch events: %1").arg(job->errorString())); - return; - } - - FetchListJob *fetchJob = dynamic_cast< FetchListJob* >(job); - Collection collection = fetchJob->property("collection").value< Collection >(); - DefaultReminderAttribute *attr = dynamic_cast< DefaultReminderAttribute* >(collection.attribute("defaultReminders")); - - Item::List removed; - Item::List changed; - QMap< QString, Objects::Event* > recurrentEvents; - - QList< Object *> allData = fetchJob->items(); - Q_FOREACH(Object * replyData, allData) { - - Objects::Event *event = static_cast< Objects::Event* >(replyData); - - if (event->useDefaultReminders() && attr) { - Alarm::List alarms = attr->alarms(event); - Q_FOREACH (AlarmPtr alarm, alarms) { - event->addAlarm(alarm); - } - } - - /* If this is a recurrent event then put it to map and continue with - * next event. We will return to this later... */ - if (event->recurs() && !event->deleted()) { - recurrentEvents.insert(event->uid(), event); - continue; - } - - /* If the event is deleted, but it has same ID as some of the recurrent - * events stored in the map, then take the original recurrent event from the map - * and set date of this particular instance as an exception date and continue. - * We will process content of the map later */ - if (event->deleted() && recurrentEvents.contains(event->uid())) { - Objects::Event *rEvent = recurrentEvents.value(event->uid()); - - rEvent->recurrence()->addExDate(event->dtStart().date()); - continue; - } - - Item item; - item.setRemoteId(event->uid()); - item.setRemoteRevision(event->etag()); - item.setPayload< EventPtr >(EventPtr(event)); - item.setMimeType(EVENT_MIMETYPE); - item.setParentCollection(collection); - - if (event->deleted()) - removed << item; - else - changed << item; - - } - - /* Now process the recurrent events */ - Q_FOREACH(Objects::Event * event, recurrentEvents.values()) { - - Item item; - item.setRemoteId(event->uid()); - item.setRemoteRevision(event->etag()); - item.setPayload< EventPtr >(EventPtr(event)); - item.setMimeType(EVENT_MIMETYPE); - item.setParentCollection(collection); - - changed << item; - } - - itemsRetrievedIncremental(changed, removed); - - collection.setRemoteRevision(QString::number(KDateTime::currentUtcDateTime().toTime_t())); - CollectionModifyJob *modifyJob = new CollectionModifyJob(collection, this); - modifyJob->setAutoDelete(true); - modifyJob->start(); -} - -void CalendarResource::eventCreated(KGoogle::Reply *reply) -{ - if (reply->error() != OK) { - cancelTask(i18n("Failed to create a new event: %1").arg(reply->errorString())); - return; - } - - QList< Object* > data = reply->replyData(); - if (data.length() != 1) { - kWarning() << "Server send " << data.length() << "items, which is not OK"; - cancelTask(i18n("Expected a single item, server sent %1 items.").arg(data.length())); - return; - } - - Objects::Event *event = static_cast< Objects::Event* >(data.first()); - - Item item = reply->request()->property("Item").value(); - item.setPayload< EventPtr >(EventPtr(event)); - item.setRemoteId(event->uid()); - item.setRemoteRevision(event->etag()); - item.setMimeType(EVENT_MIMETYPE); - item.setParentCollection(reply->request()->property("Collection").value()); - - changeCommitted(item); -} - -void CalendarResource::eventUpdated(KGoogle::Reply *reply) -{ - if (reply->error() != OK) { - cancelTask(i18n("Failed to update an event: %1").arg(reply->errorString())); - return; - } - - QList< Object* > data = reply->replyData(); - if (data.length() != 1) { - kWarning() << "Server send " << data.length() << "items, which is not OK"; - cancelTask(i18n("Expected a single item, server sent %1 items.").arg(data.length())); - return; - } - - Objects::Event *event = static_cast< Objects::Event* >(data.first()); - - Item item = reply->request()->property("Item").value(); - item.setRemoteRevision(event->etag()); - - changeCommitted(item); -} - -void CalendarResource::eventRemoved(KGoogle::Reply *reply) -{ - if (reply->error() != NoContent) { - cancelTask(i18n("Failed to delete event: %1").arg(reply->errorString())); - return; - } - - Item item = reply->request()->property("Item").value(); - changeCommitted(item); -} - -void CalendarResource::eventMoved(KGoogle::Reply *reply) -{ - if (reply->error() != OK) { - cancelTask(i18n("Failed to move event: %1").arg(reply->errorString())); - return; - } - - Item item = reply->request()->property("Item").value(); - changeCommitted(item); -} - diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/resource_tasks.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/resource_tasks.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/resource_tasks.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/resource_tasks.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,325 +0,0 @@ -/* - Akonadi Google - Calendar Resource - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#include "calendarresource.h" -#include "settings.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - - -using namespace Akonadi; -using namespace KGoogle; - -#ifdef WITH_KCAL -using namespace KCal; -#define TODO_MIMETYPE "application/x-vnd.akonadi.calendar.todo" -#else -using namespace KCalCore; -#define TODO_MIMETYPE Todo::todoMimeType() -#endif - - -void CalendarResource::taskDoUpdate(Reply* reply) -{ - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return; - } - - Item item = reply->request()->property("Item").value< Item >(); - TodoPtr todo = item.payload< TodoPtr >(); - Objects::Task ktodo(*todo); - - QUrl url = Services::Tasks::updateTaskUrl(item.parentCollection().remoteId(), item.remoteId()); - - Services::Tasks service; - QByteArray data = service.objectToJSON(static_cast< KGoogle::Object *>(&ktodo)); - - Request *request = new Request(url, Request::Update, "Tasks", account); - request->setRequestData(data, "application/json"); - request->setProperty("Item", QVariant::fromValue(item)); - m_gam->sendRequest(request); -} - - -void CalendarResource::taskListReceived(KJob *job) -{ - if (job->error()) { - cancelTask(); - Q_EMIT status(Broken, i18n("Failed to fetch task lists")); - return; - } - - FetchListJob *fetchJob = dynamic_cast< FetchListJob* >(job); - - QStringList taskLists = Settings::self()->taskLists(); - - QList< Object* > data = fetchJob->items(); - Q_FOREACH(Object * replyData, data) { - - Objects::TaskList *taskList = static_cast< Objects::TaskList* >(replyData); - - if (!taskLists.contains(taskList->uid())) - continue; - - Collection collection; - collection.setRemoteId(taskList->uid()); - collection.setParentCollection(m_collections.first()); - collection.setContentMimeTypes(QStringList() << TODO_MIMETYPE); - collection.setName(taskList->title()); - collection.setRights(Collection::AllRights); - - EntityDisplayAttribute *attr = new EntityDisplayAttribute; - attr->setDisplayName(taskList->title()); - attr->setIconName("text-calendar"); - collection.addAttribute(attr); - - m_collections.append(collection); - - } - - m_fetchedTaskLists = true; - - if (m_fetchedTaskLists && m_fetchedCalendars) { - collectionsRetrieved(m_collections); - m_collections.clear(); - - m_fetchedCalendars = false; - m_fetchedTaskLists = false; - } -} - -void CalendarResource::taskReceived(KGoogle::Reply *reply) -{ - if (reply->error() != OK) { - cancelTask(i18n("Failed to fetch task: %1").arg(reply->errorString())); - return; - } - - QList< Object* > data = reply->replyData(); - if (data.length() != 1) { - kWarning() << "Server send " << data.length() << "items, which is not OK"; - cancelTask(i18n("Expected a single item, server sent %1 items.").arg(data.length())); - return; - } - - Objects::Task *task = static_cast< Objects::Task* >(data.first()); - - Item item = reply->request()->property("Item").value(); - item.setRemoteId(task->uid()); - item.setRemoteRevision(task->etag()); - item.setMimeType(TODO_MIMETYPE); - item.setPayload< TodoPtr >(TodoPtr(task)); - - if (static_cast< Objects::Task* >(task)->deleted()) { - itemsRetrievedIncremental(Item::List(), Item::List() << item); - } else { - itemRetrieved(item); - } -} - -void CalendarResource::tasksReceived(KJob *job) -{ - if (job->error()) { - cancelTask(i18n("Failed to fetch tasks: %1").arg(job->errorString())); - return; - } - - FetchListJob *fetchJob = dynamic_cast< FetchListJob* >(job); - Collection collection = fetchJob->property("collection").value< Collection >(); - - Item::List removed; - Item::List changed; - - QList< Object* > data = fetchJob->items(); - Q_FOREACH(Object * replyData, data) { - - Objects::Task *task = static_cast< Objects::Task* >(replyData); - - Item item; - item.setRemoteId(task->uid()); - item.setRemoteRevision(task->etag()); - item.setPayload< TodoPtr >(TodoPtr(task)); - item.setMimeType(TODO_MIMETYPE); - item.setParentCollection(collection); - - if (task->deleted()) { - removed << item; - } else { - changed << item; - } - - } - - itemsRetrievedIncremental(changed, removed); - - collection.setRemoteRevision(QString::number(KDateTime::currentUtcDateTime().toTime_t())); - CollectionModifyJob *modifyJob = new CollectionModifyJob(collection, this); - modifyJob->setAutoDelete(true); - modifyJob->start(); -} - -void CalendarResource::taskCreated(KGoogle::Reply *reply) -{ - if (reply->error() != OK) { - cancelTask(i18n("Failed to create a task: %1").arg(reply->errorString())); - return; - } - - QList< Object* > data = reply->replyData(); - if (data.length() != 1) { - kWarning() << "Server send " << data.length() << "items, which is not OK"; - cancelTask(i18n("Expected a single item, server sent %1 items.").arg(data.length())); - return; - } - - Objects::Task *task = static_cast< Objects::Task* >(data.first()); - - Item item = reply->request()->property("Item").value(); - item.setRemoteId(task->uid()); - item.setRemoteRevision(task->etag()); - item.setMimeType(TODO_MIMETYPE); - item.setParentCollection(reply->request()->property("Collection").value()); - - changeCommitted(item); -} - -void CalendarResource::taskUpdated(KGoogle::Reply *reply) -{ - if (reply->error() != OK) { - cancelTask(i18n("Failed to update task: %1").arg(reply->errorString())); - return; - } - - QList< Object* > data = reply->replyData(); - if (data.length() != 1) { - kWarning() << "Server send " << data.length() << "items, which is not OK"; - cancelTask(i18n("Expected a single item, server sent %1 items.").arg(data.length())); - return; - } - - Objects::Task *task = static_cast< Objects::Task* >(data.first()); - - Item item = reply->request()->property("Item").value(); - item.setRemoteRevision(task->etag()); - - changeCommitted(item); -} - -void CalendarResource::removeTaskFetchJobFinished(KJob *job) -{ - if (job->error()) { - cancelTask(i18n("Failed to delete task (1): %1").arg(job->errorString())); - return; - } - - ItemFetchJob *fetchJob = dynamic_cast< ItemFetchJob* >(job); - Item removedItem = fetchJob->property("Item").value< Item >(); - - Item::List detachItems; - - Item::List items = fetchJob->items(); - Q_FOREACH (Item item, items) - { - if (!item.hasPayload< TodoPtr >()) { - kDebug() << "Item " << item.remoteId() << " does not have Todo payload"; - continue; - } - - TodoPtr todo = item.payload< TodoPtr >(); - /* If this item is child of the item we want to remove then add it to detach list */ -#ifdef WITH_KCAL - if (todo->relatedToUid() == removedItem.remoteId()) { - todo->setRelatedToUid(QString()); - item.setPayload(todo); - detachItems << item; - } -#else - if (todo->relatedTo(KCalCore::Incidence::RelTypeParent) == removedItem.remoteId()) { - todo->setRelatedTo(QString(), KCalCore::Incidence::RelTypeParent); - item.setPayload(todo); - detachItems << item; - } -#endif - } - - /* If there are no items do detach, then delete the task right now */ - if (detachItems.isEmpty()) { - doRemoveTask(job); - return; - } - - /* Send modify request to detach all the sub-tasks from the task that is about to be - * removed. */ - - ItemModifyJob *modifyJob = new ItemModifyJob(detachItems); - modifyJob->setProperty("Item", qVariantFromValue(removedItem)); - modifyJob->setAutoDelete(true); - connect(modifyJob, SIGNAL(finished(KJob*)), this, SLOT(doRemoveTask(KJob*))); - modifyJob->start(); -} - -void CalendarResource::doRemoveTask(KJob *job) -{ - if (job->error()) { - cancelTask(i18n("Failed to delete task (2): %1").arg(job->errorString())); - return; - } - - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return; - } - - Item item = job->property("Item").value< Item >(); - - /* Now finally we can safely remove the task we wanted to */ - Request *request = new Request(Services::Tasks::removeTaskUrl(item.parentCollection().remoteId(), item.remoteId()), - KGoogle::Request::Remove, "Tasks", account); - request->setProperty("Item", qVariantFromValue(item)); - m_gam->sendRequest(request); -} - -void CalendarResource::taskRemoved(KGoogle::Reply *reply) -{ - if (reply->error() != NoContent) { - cancelTask(i18n("Failed to delete task (5): %1").arg(reply->errorString())); - return; - } - - Item item = reply->request()->property("Item").value(); - changeCommitted(item); -} diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/settingsbase.kcfg akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/settingsbase.kcfg --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/settingsbase.kcfg 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/settingsbase.kcfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - 30 - - - - true - - - diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/settingsbase.kcfgc akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/settingsbase.kcfgc --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/settingsbase.kcfgc 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/settingsbase.kcfgc 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -File=settingsbase.kcfg -ClassName=SettingsBase -Mutators=true -ItemAccessors=true -SetUserTexts=true -Singleton=false -GlobalEnums=true \ No newline at end of file diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/settings.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/settings.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/settings.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/settings.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -/* - Akonadi Google - Contacts Resource - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "settings.h" -#include "settingsbase.h" -#include "settingsadaptor.h" - -#include -#include - -#include - -class SettingsHelper -{ - public: - SettingsHelper(): q(0) {}; - ~SettingsHelper() { - delete q; - q = 0; - } - - Settings *q; -}; - -K_GLOBAL_STATIC(SettingsHelper, s_globalSettings) - -Settings::Settings() -{ - Q_ASSERT(!s_globalSettings->q); - s_globalSettings->q = this; - - new SettingsAdaptor(this); - QDBusConnection::sessionBus().registerObject(QLatin1String("/Settings"), this, - QDBusConnection::ExportAdaptors | QDBusConnection::ExportScriptableContents); -} - -Settings* Settings::self() -{ - if (!s_globalSettings->q) { - new Settings; - s_globalSettings->q->readConfig(); - } - - return s_globalSettings->q; - -} - -QString Settings::clientId() const -{ - return "554041944266.apps.googleusercontent.com"; -} - -QString Settings::clientSecret() const -{ - return "mdT1DjzohxN3npUUzkENT0gO"; -} - -void Settings::setWindowId(WId id) -{ - m_winId = id; -} - -void Settings::setResourceId(const QString &resourceIdentificator) -{ - m_resourceId = resourceIdentificator; -} diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/settingsdialog.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/settingsdialog.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/settingsdialog.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/settingsdialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,756 +0,0 @@ -/* - Akonadi Google - Calendar Resource - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "calendareditor.h" -#include "settingsdialog.h" -#include "settings.h" -#include "tasklisteditor.h" -#include "ui_settingsdialog.h" - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace KGoogle; - -enum { - KGoogleObjectRole = Qt::UserRole, - ObjectUIDRole = Qt::UserRole + 1 -}; - -SettingsDialog::SettingsDialog(WId windowId, QWidget* parent): - KDialog(parent), - m_windowId(windowId) -{ - qRegisterMetaType("Calendar"); - qRegisterMetaType("Tasks"); - - KWindowSystem::setMainWindow(this, windowId); - - m_ui = new ::Ui::SettingsDialog(); - m_ui->setupUi(this->mainWidget()); - - m_ui->addAccountBtn->setIcon(QIcon::fromTheme("list-add-user")); - m_ui->removeAccountBtn->setIcon(QIcon::fromTheme("list-remove-user")); - m_ui->reloadCalendarsBtn->setIcon(QIcon::fromTheme("view-refresh")); - m_ui->addCalBtn->setIcon(QIcon::fromTheme("list-add")); - m_ui->removeCalBtn->setIcon(QIcon::fromTheme("list-remove")); - m_ui->reloadTasksBtn->setIcon(QIcon::fromTheme("view-refresh")); - m_ui->addTasksBtn->setIcon(QIcon::fromTheme("list-add")); - m_ui->removeTasksBtn->setIcon(QIcon::fromTheme("list-remove")); - - connect(m_ui->addAccountBtn, SIGNAL(clicked()), - this, SLOT(addAccountClicked())); - connect(m_ui->removeAccountBtn, SIGNAL(clicked()), - this, SLOT(removeAccountClicked())); - connect(m_ui->accountsCombo, SIGNAL(currentIndexChanged(int)), - this, SLOT(accountChanged())); - connect(m_ui->addCalBtn, SIGNAL(clicked()), - this, SLOT(addCalendarClicked())); - connect(m_ui->editCalBtn, SIGNAL(clicked()), - this, SLOT(editCalendarClicked())); - connect(m_ui->calendarsList, SIGNAL(itemDoubleClicked(QListWidgetItem*)), - this, SLOT(editCalendarClicked())); - connect(m_ui->removeCalBtn, SIGNAL(clicked()), - this, SLOT(removeCalendarClicked())); - connect(m_ui->reloadCalendarsBtn, SIGNAL(clicked()), - this, SLOT(reloadCalendarsClicked())); - connect(m_ui->addTasksBtn, SIGNAL(clicked()), - this, SLOT(addTaskListClicked())); - connect(m_ui->editTasksBtn, SIGNAL(clicked()), - this, SLOT(editTaskListClicked())); - connect(m_ui->tasksList, SIGNAL(itemDoubleClicked(QListWidgetItem*)), - this, SLOT(editTaskListClicked())); - connect(m_ui->removeTasksBtn, SIGNAL(clicked()), - this, SLOT(removeTaskListClicked())); - connect(m_ui->reloadTasksBtn, SIGNAL(clicked()), - this, SLOT(reloadTaskListsClicked())); - - connect(this, SIGNAL(accepted()), - this, SLOT(saveSettings())); - - m_gam = new KGoogle::AccessManager; - connect(m_gam, SIGNAL(replyReceived(KGoogle::Reply*)), - this, SLOT(gam_objectsListReceived(KGoogle::Reply*))); - connect(m_gam, SIGNAL(error(KGoogle::Error,QString)), - this, SLOT(error(KGoogle::Error,QString))); - - KGoogle::Auth *auth = KGoogle::Auth::instance(); - connect(auth, SIGNAL(authenticated(KGoogle::Account::Ptr&)), - this, SLOT(reloadAccounts())); - - m_ui->accountsCombo->clear(); - reloadAccounts(); -} - -SettingsDialog::~SettingsDialog() -{ - Settings::self()->writeConfig(); - - delete m_gam; - - delete m_ui; -} - -void SettingsDialog::error (KGoogle::Error code, const QString &msg) -{ - KMessageBox::sorry(this, msg, i18n("Error while talking to Google")); - - m_ui->accountsBox->setEnabled(true); - m_ui->calendarsBox->setEnabled(true); - m_ui->tasksBox->setEnabled(true); - - Q_UNUSED(code) -} - - -void SettingsDialog::saveSettings() -{ - Settings::self()->setAccount(m_ui->accountsCombo->currentText()); - - QStringList calendars; - for (int i = 0; i < m_ui->calendarsList->count(); i++) { - QListWidgetItem *item = m_ui->calendarsList->item(i); - - if (item->checkState() == Qt::Checked) { - calendars.append(item->data(ObjectUIDRole).toString()); - } - } - Settings::self()->setCalendars(calendars); - - QStringList taskLists; - for (int i = 0; i < m_ui->tasksList->count(); i++) { - QListWidgetItem *item = m_ui->tasksList->item(i); - - if (item->checkState() == Qt::Checked) { - taskLists.append(item->data(ObjectUIDRole).toString()); - } - } - Settings::self()->setTaskLists(taskLists); - - Settings::self()->writeConfig(); -} - -void SettingsDialog::reloadAccounts() -{ - disconnect(m_ui->accountsCombo, SIGNAL(currentIndexChanged(int)), - this, SLOT(accountChanged())); - - int accCnt = m_ui->accountsCombo->count(); - m_ui->accountsCombo->reload(); - - QString accName = Settings::self()->account(); - int index = m_ui->accountsCombo->findText(accName); - if (index > -1) { - m_ui->accountsCombo->setCurrentIndex(index); - } - - if (accCnt != m_ui->accountsCombo->count()) - accountChanged(); - - connect(m_ui->accountsCombo, SIGNAL(currentIndexChanged(int)), - this, SLOT(accountChanged())); -} - -void SettingsDialog::addAccountClicked() -{ - KGoogle::Auth *auth = KGoogle::Auth::instance(); - - KGoogle::Account::Ptr account(new KGoogle::Account()); - account->addScope(Services::Calendar::ScopeUrl); - account->addScope(Services::Tasks::ScopeUrl); - - try { - auth->authenticate(account, true); - } catch (KGoogle::Exception::BaseException &e) { - KMessageBox::error(this, e.what()); - } -} - -void SettingsDialog::removeAccountClicked() -{ - KGoogle::Account::Ptr account = m_ui->accountsCombo->currentAccount(); - if (account.isNull()) - return; - - if (KMessageBox::warningYesNo( - this, - i18n("Do you really want to revoke access to account %1?" - "
This will revoke access to all application using this account!", account->accountName()), - i18n("Revoke Access?"), - KStandardGuiItem::yes(), KStandardGuiItem::no(), QString(), KMessageBox::Dangerous) != KMessageBox::Yes) { - - return; - } - - KGoogle::Auth *auth = KGoogle::Auth::instance(); - try { - auth->revoke(account); - } catch (KGoogle::Exception::BaseException &e) { - KMessageBox::error(this, e.what()); - } - - reloadAccounts(); -} - -void SettingsDialog::accountChanged() -{ - m_ui->accountsBox->setDisabled(true); - m_ui->calendarsBox->setDisabled(true); - m_ui->tasksBox->setDisabled(true); - - Account::Ptr account = m_ui->accountsCombo->currentAccount(); - if (account.isNull()) { - m_ui->accountsBox->setEnabled(true); - m_ui->calendarsList->clear(); - m_ui->calendarsBox->setEnabled(true); - m_ui->tasksList->clear(); - m_ui->tasksBox->setEnabled(true); - return; - } - - KGoogle::Request *request; - - m_ui->calendarsList->clear(); - request = new KGoogle::Request(Services::Calendar::fetchCalendarsUrl(), Request::FetchAll, "Calendar", account); - m_gam->queueRequest(request); - - m_ui->tasksList->clear(); - request = new KGoogle::Request(Services::Tasks::fetchTaskListsUrl(), Request::FetchAll, "Tasks", account); - m_gam->sendRequest(request); -} - -void SettingsDialog::addCalendarClicked() -{ - CalendarEditor *editor = new CalendarEditor; - connect(editor, SIGNAL(accepted(KGoogle::Objects::Calendar*)), - this, SLOT(addCalendar(KGoogle::Objects::Calendar*))); - - editor->exec(); - - delete editor; -} - -void SettingsDialog::addCalendar(KGoogle::Objects::Calendar *calendar) -{ - KGoogle::Account::Ptr account; - KGoogle::AccessManager *gam; - KGoogle::Request *request; - Services::Calendar parser; - QByteArray data; - - account = m_ui->accountsCombo->currentAccount(); - if (account.isNull()) - return; - - m_ui->accountsBox->setDisabled(true); - m_ui->calendarsBox->setDisabled(true); - - gam = new KGoogle::AccessManager; - connect(gam, SIGNAL(replyReceived(KGoogle::Reply*)), - this, SLOT(gam_objectCreated(KGoogle::Reply*))); - connect(gam, SIGNAL(requestFinished(KGoogle::Request*)), - gam, SLOT(deleteLater())); - - request = new KGoogle::Request(Services::Calendar::createCalendarUrl(), - Request::Create, "Calendar", account); - data = parser.objectToJSON(dynamic_cast< KGoogle::Object* >(calendar)); - request->setRequestData(data, "application/json"); - gam->sendRequest(request); - - delete calendar; -} - -void SettingsDialog::editCalendarClicked() -{ - Objects::Calendar *calendar; - QListWidgetItem *item; - QList< QListWidgetItem* > selected; - - selected = m_ui->calendarsList->selectedItems(); - if (selected.isEmpty()) - return; - - item = selected.first(); - if (!item) - return; - - calendar = item->data(KGoogleObjectRole).value< KGoogle::Objects::Calendar* >(); - if (!calendar) - return; - - CalendarEditor *editor = new CalendarEditor(calendar); - connect(editor, SIGNAL(accepted(KGoogle::Objects::Calendar*)), - this, SLOT(editCalendar(KGoogle::Objects::Calendar*))); - - editor->exec(); - - delete editor; -} - -void SettingsDialog::editCalendar(KGoogle::Objects::Calendar *calendar) -{ - KGoogle::Account::Ptr account; - KGoogle::AccessManager *gam; - KGoogle::Request *request; - Services::Calendar parser; - QByteArray data; - - account = m_ui->accountsCombo->currentAccount(); - if (account.isNull()) - return; - - m_ui->accountsBox->setDisabled(true); - m_ui->calendarsBox->setDisabled(true); - - gam = new KGoogle::AccessManager; - connect(gam, SIGNAL(replyReceived(KGoogle::Reply*)), - this, SLOT(gam_objectModified(KGoogle::Reply*))); - connect(gam, SIGNAL(requestFinished(KGoogle::Request*)), - gam, SLOT(deleteLater())); - - request = new KGoogle::Request(Services::Calendar::updateCalendarUrl(calendar->uid()), - Request::Update, "Calendar", account); - data = parser.objectToJSON(dynamic_cast< KGoogle::Object* >(calendar)); - request->setRequestData(data, "application/json"); - gam->sendRequest(request); - - delete calendar; -} - -void SettingsDialog::removeCalendarClicked() -{ - Objects::Calendar *calendar; - QListWidgetItem *item; - QList< QListWidgetItem* > selected; - - selected = m_ui->calendarsList->selectedItems(); - if (selected.isEmpty()) - return; - - item = selected.first(); - if (!item) - return; - - calendar = item->data(KGoogleObjectRole).value< KGoogle::Objects::Calendar* >(); - if (!calendar) - return; - - if (KMessageBox::warningYesNo(this, - i18n("Do you really want to remove calendar %1?
" - "This will remove the calendar from Google servers as well!", calendar->title()), - i18n("Remove Calendar?"), - KStandardGuiItem::yes(), KStandardGuiItem::no(), QString(), KMessageBox::Dangerous) != KStandardGuiItem::Yes) { - - return; - } - - KGoogle::Account::Ptr account; - KGoogle::AccessManager *gam; - KGoogle::Request *request; - - account = m_ui->accountsCombo->currentAccount(); - if (account.isNull()) - return; - - m_ui->accountsBox->setDisabled(true); - m_ui->calendarsBox->setDisabled(true); - - gam = new KGoogle::AccessManager; - connect(gam, SIGNAL(replyReceived(KGoogle::Reply*)), - this, SLOT(reloadCalendarsClicked())); - connect(gam, SIGNAL(requestFinished(KGoogle::Request*)), - gam, SLOT(deleteLater())); - - request = new KGoogle::Request(Services::Calendar::removeCalendarUrl(calendar->uid()), - Request::Remove, "Calendar", account); - gam->sendRequest(request); -} - -void SettingsDialog::addTaskListClicked() -{ - TasklistEditor *editor = new TasklistEditor; - connect(editor, SIGNAL(accepted(KGoogle::Objects::TaskList*)), - this, SLOT(addTaskList(KGoogle::Objects::TaskList*))); - - editor->exec(); - - delete editor; -} - -void SettingsDialog::reloadCalendarsClicked() -{ - KGoogle::AccessManager *gam; - KGoogle::Account::Ptr account; - KGoogle::Request *request; - - account = m_ui->accountsCombo->currentAccount(); - if (account.isNull()) - return; - - m_ui->accountsBox->setDisabled(true); - m_ui->calendarsBox->setDisabled(true); - - m_ui->calendarsList->clear(); - gam = new KGoogle::AccessManager; - connect(gam, SIGNAL(replyReceived(KGoogle::Reply*)), - this, SLOT(gam_objectsListReceived(KGoogle::Reply*))); - connect(gam, SIGNAL(requestFinished(KGoogle::Request*)), - gam, SLOT(deleteLater())); - - request = new KGoogle::Request(Services::Calendar::fetchCalendarsUrl(), Request::FetchAll, "Calendar", account); - gam->sendRequest(request); -} - -void SettingsDialog::addTaskList(TaskList *taskList) -{ - KGoogle::Account::Ptr account; - KGoogle::AccessManager *gam; - KGoogle::Request *request; - Services::Tasks parser; - QByteArray data; - - account = m_ui->accountsCombo->currentAccount(); - if (account.isNull()) - return; - - m_ui->accountsBox->setDisabled(true); - m_ui->tasksBox->setDisabled(true); - - gam = new KGoogle::AccessManager; - connect(gam, SIGNAL(replyReceived(KGoogle::Reply*)), - this, SLOT(gam_objectCreated(KGoogle::Reply*))); - connect(gam, SIGNAL(requestFinished(KGoogle::Request*)), - gam, SLOT(deleteLater())); - - request = new KGoogle::Request(Services::Tasks::createTaskListUrl(), Request::Create, "Tasks", account); - data = parser.objectToJSON(dynamic_cast< KGoogle::Object* >(taskList)); - request->setRequestData(data, "application/json"); - gam->sendRequest(request); - - delete taskList; -} - -void SettingsDialog::editTaskListClicked() -{ - Objects::TaskList *taskList; - QListWidgetItem *item; - QList< QListWidgetItem* > selected; - - selected = m_ui->tasksList->selectedItems(); - if (selected.isEmpty()) - return; - - item = selected.first(); - if (!item) - return; - - taskList = item->data(KGoogleObjectRole).value< KGoogle::Objects::TaskList* >(); - if (!taskList) - return; - - TasklistEditor *editor = new TasklistEditor(taskList); - connect(editor, SIGNAL(accepted(KGoogle::Objects::TaskList*)), - this, SLOT(editTaskList(KGoogle::Objects::TaskList*))); - - editor->exec(); - - delete editor; -} - -void SettingsDialog::editTaskList(TaskList *taskList) -{ - KGoogle::Account::Ptr account; - KGoogle::AccessManager *gam; - KGoogle::Request *request; - Services::Tasks parser; - QByteArray data; - - account = m_ui->accountsCombo->currentAccount(); - if (account.isNull()) - return; - - m_ui->accountsBox->setDisabled(true); - m_ui->tasksBox->setDisabled(true); - - gam = new KGoogle::AccessManager; - connect(gam, SIGNAL(replyReceived(KGoogle::Reply*)), - this, SLOT(gam_objectModified(KGoogle::Reply*))); - connect(gam, SIGNAL(requestFinished(KGoogle::Request*)), - gam, SLOT(deleteLater())); - - request = new KGoogle::Request(Services::Tasks::updateTaskListUrl(taskList->uid()), - Request::Update, "Tasks", account); - data = parser.objectToJSON(dynamic_cast< KGoogle::Object* >(taskList)); - request->setRequestData(data, "application/json"); - gam->sendRequest(request); - - delete taskList; -} - -void SettingsDialog::removeTaskListClicked() -{ - Objects::TaskList *taskList; - QListWidgetItem *item; - QList< QListWidgetItem* > selected; - - selected = m_ui->calendarsList->selectedItems(); - if (selected.isEmpty()) - return; - - item = selected.first(); - if (!item) - return; - - taskList = item->data(KGoogleObjectRole).value< KGoogle::Objects::TaskList* >(); - if (!taskList) - return; - - if (KMessageBox::warningYesNo(this, - i18n("Do you really want to remove tasklist %1?
" - "This will remove the tasklist from Google servers as well!", taskList->title()), - i18n("Remove tasklist?"), - KStandardGuiItem::yes(), KStandardGuiItem::no(), QString(), KMessageBox::Dangerous) != KStandardGuiItem::Yes) { - - return; - } - - KGoogle::Account::Ptr account; - KGoogle::AccessManager *gam; - KGoogle::Request *request; - - account = m_ui->accountsCombo->currentAccount(); - if (account.isNull()) - return; - - m_ui->accountsBox->setDisabled(true); - m_ui->tasksBox->setDisabled(true); - - gam = new KGoogle::AccessManager; - connect(gam, SIGNAL(replyReceived(KGoogle::Reply*)), - this, SLOT(reloadTaskListsClicked())); - connect(gam, SIGNAL(requestFinished(KGoogle::Request*)), - gam, SLOT(deleteLater())); - - request = new KGoogle::Request(Services::Tasks::removeTaskListUrl(taskList->uid()), - Request::Remove, "Tasks", account); - gam->sendRequest(request); -} - -void SettingsDialog::reloadTaskListsClicked() -{ - KGoogle::AccessManager *gam; - KGoogle::Account::Ptr account; - KGoogle::Request *request; - - account = m_ui->accountsCombo->currentAccount(); - if (!account) - return; - - m_ui->accountsBox->setDisabled(true); - m_ui->tasksBox->setDisabled(true); - - m_ui->tasksList->clear(); - - gam = new KGoogle::AccessManager; - connect(gam, SIGNAL(replyReceived(KGoogle::Reply*)), - this, SLOT(gam_objectsListReceived(KGoogle::Reply*))); - connect(gam, SIGNAL(requestFinished(KGoogle::Request*)), - gam, SLOT(deleteLater())); - - request = new KGoogle::Request(Services::Tasks::fetchTaskListsUrl(), Request::FetchAll, "Tasks", account); - gam->sendRequest(request); -} - -void SettingsDialog::gam_objectCreated(Reply *reply) -{ - QList< KGoogle::Object* > objects = reply->replyData(); - - if (reply->serviceName() == "Calendar") { - - Q_FOREACH(KGoogle::Object * object, objects) { - KGoogle::Objects::Calendar *calendar = static_cast< KGoogle::Objects::Calendar* >(object); - - QListWidgetItem *item = new QListWidgetItem(calendar->title()); - item->setData(KGoogleObjectRole, qVariantFromValue(calendar)); - item->setData(ObjectUIDRole, calendar->uid()); - item->setCheckState(Qt::Unchecked); - - m_ui->calendarsList->addItem(item); - } - - m_ui->calendarsBox->setEnabled(true); - m_ui->accountsBox->setEnabled(true); - - } else if (reply->serviceName() == "Tasks") { - - Q_FOREACH(KGoogle::Object * object, objects) { - KGoogle::Objects::TaskList *taskList = static_cast< KGoogle::Objects::TaskList* >(object); - - QListWidgetItem *item = new QListWidgetItem(taskList->title()); - item->setData(KGoogleObjectRole, qVariantFromValue(taskList)); - item->setData(ObjectUIDRole, taskList->uid()); - item->setCheckState(Qt::Unchecked); - - m_ui->tasksList->addItem(item); - } - - m_ui->tasksBox->setEnabled(true); - m_ui->accountsBox->setEnabled(true); - - } - - delete reply; -} - - -void SettingsDialog::gam_objectsListReceived(Reply *reply) -{ - QList< KGoogle::Object* > objects = reply->replyData(); - - if (reply->serviceName() == "Calendar") { - - Q_FOREACH(KGoogle::Object * object, objects) { - Objects::Calendar *calendar; - QListWidgetItem *item; - - calendar = static_cast< Objects::Calendar* >(object); - item = new QListWidgetItem; - item->setText(calendar->title()); - item->setData(KGoogleObjectRole, qVariantFromValue(calendar)); - item->setData(ObjectUIDRole, calendar->uid()); - - if (Settings::self()->calendars().contains(calendar->uid())) - item->setCheckState(Qt::Checked); - else - item->setCheckState(Qt::Unchecked); - - m_ui->calendarsList->addItem(item); - } - - m_ui->calendarsBox->setEnabled(true); - delete reply; - - } else if (reply->serviceName() == "Tasks") { - - Q_FOREACH(KGoogle::Object * object, objects) { - Objects::TaskList *taskList; - QListWidgetItem *item; - - taskList = static_cast< Objects::TaskList* >(object); - item = new QListWidgetItem; - item->setText(taskList->title()); - item->setData(KGoogleObjectRole, qVariantFromValue(taskList)); - item->setData(ObjectUIDRole, taskList->uid()); - - if (Settings::self()->taskLists().contains(taskList->uid())) - item->setCheckState(Qt::Checked); - else - item->setCheckState(Qt::Unchecked); - - m_ui->tasksList->addItem(item); - } - - m_ui->tasksBox->setEnabled(true); - delete reply; - - } - - if (m_ui->calendarsBox->isEnabled() && m_ui->tasksList->isEnabled()) - m_ui->accountsBox->setEnabled(true); -} - -void SettingsDialog::gam_objectModified(Reply *reply) -{ - QList< KGoogle::Object* > objects = reply->replyData(); - - if (reply->serviceName() == "Calendar") { - - Q_FOREACH(KGoogle::Object * object, objects) { - KGoogle::Objects::Calendar *calendar = static_cast< KGoogle::Objects::Calendar* >(object); - QListWidgetItem *item = 0; - - for (int i = 0; i < m_ui->calendarsList->count(); i++) { - QListWidgetItem *t = m_ui->calendarsList->item(i); - - if (t->data(ObjectUIDRole).toString() == calendar->uid()) { - item = t; - break; - } - } - - if (!item) { - item = new QListWidgetItem; - m_ui->calendarsList->addItem(item); - } - - item->setText(calendar->title()); - item->setData(ObjectUIDRole, calendar->uid()); - item->setData(KGoogleObjectRole, qVariantFromValue(calendar)); - } - - m_ui->calendarsBox->setEnabled(true); - m_ui->accountsBox->setEnabled(true); - - } else if (reply->serviceName() == "Tasks") { - - Q_FOREACH(KGoogle::Object * object, objects) { - KGoogle::Objects::TaskList *taskList = static_cast< KGoogle::Objects::TaskList* >(object); - QListWidgetItem *item = 0; - - for (int i = 0; i < m_ui->tasksList->count(); i++) { - QListWidgetItem *t = m_ui->tasksList->item(i); - - if (t->data(ObjectUIDRole).toString() == taskList->uid()) { - item = t; - break; - } - } - - if (!item) { - item = new QListWidgetItem; - m_ui->tasksList->addItem(item); - } - - item->setText(taskList->title()); - item->setData(ObjectUIDRole, taskList->uid()); - item->setData(KGoogleObjectRole, qVariantFromValue(taskList)); - - } - m_ui->tasksBox->setEnabled(true); - m_ui->accountsBox->setEnabled(true); - - } - - delete reply; -} diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/settingsdialog.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/settingsdialog.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/settingsdialog.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/settingsdialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -/* - Akonadi Google - Calendar Resource - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#ifndef SETTINGSDIALOG_H -#define SETTINGSDIALOG_H - -#include -#include -#include - -#include - -namespace Ui -{ -class SettingsDialog; -} - -namespace KGoogle -{ -class Reply; -class AccessManager; - -namespace Objects -{ -class Calendar; -class TaskList; -} -} - -class QListWidgetItem; - -using namespace KGoogle; - -class SettingsDialog : public KDialog -{ - Q_OBJECT - public: - SettingsDialog(WId windowId, QWidget *parent = 0); - ~SettingsDialog(); - - private Q_SLOTS: - void reloadAccounts(); - void addAccountClicked(); - void removeAccountClicked(); - void accountChanged(); - void addCalendarClicked(); - void editCalendarClicked(); - void removeCalendarClicked(); - void reloadCalendarsClicked(); - void addTaskListClicked(); - void editTaskListClicked(); - void removeTaskListClicked(); - void reloadTaskListsClicked(); - - void gam_objectsListReceived(KGoogle::Reply *reply); - void gam_objectCreated(KGoogle::Reply *reply); - void gam_objectModified(KGoogle::Reply *reply); - - void addCalendar(KGoogle::Objects::Calendar *calendar); - void editCalendar(KGoogle::Objects::Calendar *calendar); - - void addTaskList(KGoogle::Objects::TaskList *taskList); - void editTaskList(KGoogle::Objects::TaskList *taskList); - - void saveSettings(); - - void error (KGoogle::Error code, const QString &msg); - - private: - Ui::SettingsDialog *m_ui; - WId m_windowId; - AccessManager *m_gam; - - -}; - -#endif // SETTINGSDIALOG_H diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/settings.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/settings.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/settings.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/settings.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -/* - Akonadi Google - Contacts Resource - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#ifndef SETTINGS_H -#define SETTINGS_H - -#include "settingsbase.h" - -#include - -/** - * @brief Settings object - * - * Provides read-only access to application clientId and - * clientSecret and read-write access to accessToken and - * refreshToken. - */ -class Settings: public SettingsBase -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "org.kde.Akonadi.GoogleCalendar.ExtendedSettings") - public: - Settings(); - void setWindowId(WId id); - void setResourceId(const QString &resourceIdentifier); - static Settings* self(); - - QString appId() const; - - QString clientId() const; - QString clientSecret() const; - - private: - WId m_winId; - QString m_resourceId; - -}; - -#endif // SETTINGS_H diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/tasklisteditor.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/tasklisteditor.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/tasklisteditor.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/tasklisteditor.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -/* - Akonadi Google - Calendar Resource* - Copyright (C) 2012 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#include "tasklisteditor.h" -#include "ui_tasklist_editor.h" - -using namespace KGoogle::Objects; - -TasklistEditor::TasklistEditor(TaskList *taskList): - QDialog(), - m_taskList(taskList) -{ - m_ui = new ::Ui::TaskListEditor(); - m_ui->setupUi(this); - - if (m_taskList) - m_ui->nameEdit->setText(m_taskList->title()); - - connect(m_ui->buttons, SIGNAL(accepted()), - this, SLOT(accepted())); -} - -TasklistEditor::~TasklistEditor() -{ - delete m_ui; -} - -void TasklistEditor::accepted() -{ - if (!m_taskList) - m_taskList = new KGoogle::Objects::TaskList; - - m_taskList->setTitle(m_ui->nameEdit->text()); - - Q_EMIT accepted(m_taskList); -} - - - - diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/tasklisteditor.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/tasklisteditor.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/tasklisteditor.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/tasklisteditor.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,52 +0,0 @@ -/* - Akonadi Google - Calendar Resource - Copyright (C) 2012 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#ifndef TASKLISTEDITOR_H -#define TASKLISTEDITOR_H - -#include - -#include - -namespace Ui -{ -class TaskListEditor; -} - -class TasklistEditor : public QDialog -{ - Q_OBJECT - - public: - explicit TasklistEditor(KGoogle::Objects::TaskList *taskList = 0); - - virtual ~TasklistEditor(); - - Q_SIGNALS: - void accepted(KGoogle::Objects::TaskList *taskList); - - private Q_SLOTS: - void accepted(); - - private: - KGoogle::Objects::TaskList *m_taskList; - Ui::TaskListEditor *m_ui; -}; - -#endif // TASKLISTEDITOR_H diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/ui/calendar_editor.ui akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/ui/calendar_editor.ui --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/ui/calendar_editor.ui 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/ui/calendar_editor.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,111 +0,0 @@ - - - CalendarEditor - - - - 0 - 0 - 421 - 220 - - - - Calendar Editor - - - - - - Name: - - - - - - - Description: - - - - - - - Location: - - - - - - - Timezone: - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - - - - - - - - - - nameEdit - descriptionEdit - locationEdit - timezoneCombo - buttons - - - - - buttons - accepted() - CalendarEditor - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttons - rejected() - CalendarEditor - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/ui/settingsdialog.ui akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/ui/settingsdialog.ui --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/ui/settingsdialog.ui 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/ui/settingsdialog.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,204 +0,0 @@ - - - SettingsDialog - - - - 0 - 0 - 447 - 480 - - - - - 0 - 0 - - - - - 0 - 480 - - - - Calendar Resource Settings - - - - - - Accounts - - - - - - - 0 - 0 - - - - Add - - - - - - - - 0 - 0 - - - - Remove - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - 0 - 0 - - - - - - - - - - - Calendars - - - - - - Reload - - - - - - - Edit - - - - - - - Remove - - - - - - - Add - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - - - Tasks Lists - - - - - - Add - - - - - - - - - - Reload - - - - - - - Remove - - - - - - - Edit - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - KGoogle::Ui::AccountsCombo - QComboBox -
libkgoogle/ui/accountscombo.h
-
-
- - -
diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/ui/tasklist_editor.ui akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/ui/tasklist_editor.ui --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/calendar/ui/tasklist_editor.ui 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/calendar/ui/tasklist_editor.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,78 +0,0 @@ - - - TaskListEditor - - - - 0 - 0 - 421 - 92 - - - - Tasklist Editor - - - - - - - - - Name: - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - nameEdit - buttons - - - - - buttons - accepted() - TaskListEditor - accept() - - - 248 - 254 - - - 157 - 274 - - - - - buttons - rejected() - TaskListEditor - reject() - - - 316 - 260 - - - 286 - 274 - - - - - diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/CMakeLists.txt akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/CMakeLists.txt --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/CMakeLists.txt 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/CMakeLists.txt 2012-06-16 02:20:58.000000000 +0000 @@ -1,24 +1,35 @@ -cmake_minimum_required(VERSION 2.8) +project(libkgoogle) +set(KGOOGLE_VERSION_MAJOR 0) +set(KGOOGLE_VERSION_MINOR 3) +set(KGOOGLE_VERSION_RELEASE 2) +set(KGOOGLE_VERSION 0.3.2) + +cmake_minimum_required(VERSION 2.8) if(POLICY CMP0017) cmake_policy(SET CMP0017 NEW) endif() find_package(Qt4 4.7.0 REQUIRED) +option(DEBUG_RAWDATA "Log raw data send and received from Google service (enables CMAKE_BUILD_TYPE=Debug)" FALSE) +if (DEBUG_RAWDATA) + SET(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) + add_definitions(-DDEBUG_RAWDATA) +else (DEBUG_RAWDATA) + SET(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel.") +endif (DEBUG_RAWDATA) + find_package(KDE4 4.6.0 REQUIRED) include(KDE4Defaults) include(MacroLibrary) find_package(KdepimLibs 4.5.63 REQUIRED) -find_program(XSLTPROC_EXECUTABLE xsltproc) -macro_log_feature(XSLTPROC_EXECUTABLE "xsltproc" "The command line XSLT processor from libxslt" "http://xmlsoft.org/XSLT/" TRUE) - find_package(QJSON REQUIRED) macro_log_feature(QJSON_FOUND "QJSON" "Qt library for handling JSON data" "http://qjson.sourceforge.net/" TRUE) -add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS} -DQT_NO_KEYWORDS) - +add_definitions(${QT_DEFINITIONS} ${KDE4_DEFINITIONS} -DQT_NO_KEYWORDS -DLIBKGOOGLE_LIBRARY) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) option(USE_KCAL "Use deprecated KCal API instead of KCalCore API. Provides backwards compatibility for KDE PIM 4.4" FALSE) if (USE_KCAL) @@ -44,7 +55,18 @@ add_subdirectory(libkgoogle) -macro_optional_add_subdirectory(calendar) -macro_optional_add_subdirectory(contacts) - -macro_display_feature_log() +configure_file(${libkgoogle_SOURCE_DIR}/LibKGoogleConfig.cmake.in + ${libkgoogle_BINARY_DIR}/LibKGoogleConfig.cmake + @ONLY +) +# this file is used by to check if the installed version can be used. +macro_write_basic_cmake_version_file(${libkgoogle_BINARY_DIR}/LibKGoogleConfigVersion.cmake + ${KGOOGLE_VERSION_MAJOR} ${KGOOGLE_VERSION_MINOR} ${KGOOGLE_VERSION_RELEASE}) + +install(FILES ${libkgoogle_BINARY_DIR}/LibKGoogleConfig.cmake ${libkgoogle_BINARY_DIR}/LibKGoogleConfigVersion.cmake + DESTINATION ${LIB_INSTALL_DIR}/cmake/LibKGoogle) + +# Install the file with the exported targets +install(EXPORT kgoogleLibraryTargets + DESTINATION ${LIB_INSTALL_DIR}/cmake/LibKGoogle + FILE LibKGoogleTargetsWithPrefix.cmake) diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/CMakeLists.txt akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/CMakeLists.txt --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/CMakeLists.txt 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,51 +0,0 @@ -project(googlecontactsresource) -set(CONTACT_RESOURCE_VERSION 0.3.1) - -cmake_minimum_required(VERSION 2.8) - -add_definitions(-DRESOURCE_VERSION="\\"${CONTACT_RESOURCE_VERSION}\\"") -if (XSLTPROC_EXECUTABLE) - macro(kcfg_generate_dbus_interface _kcfg _name) - add_custom_command( - OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml - COMMAND ${XSLTPROC_EXECUTABLE} --stringparam interfaceName ${_name} - ${KDEPIMLIBS_DATA_DIR}/akonadi-kde/kcfg2dbus.xsl - ${_kcfg} - > ${CMAKE_CURRENT_BINARY_DIR}/${_name}.xml - DEPENDS ${KDEPIMLIBS_DATA_DIR}/akonadi-kde/kcfg2dbus.xsl - ${_kcfg} - ) - endmacro(kcfg_generate_dbus_interface) -endif (XSLTPROC_EXECUTABLE) - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - -set(contactsresource_SRCS - contactsresource.cpp - settings.cpp - settingsdialog.cpp -) - -kde4_add_ui_files(contactsresource_SRCS ui/settingsdialog.ui ui/groupeditor.ui) -kde4_add_kcfg_files(contactsresource_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/settingsbase.kcfgc) -kcfg_generate_dbus_interface(${CMAKE_CURRENT_SOURCE_DIR}/settingsbase.kcfg org.kde.Akonadi.GoogleContacts.Settings) -qt4_add_dbus_adaptor(contactsresource_SRCS - ${CMAKE_CURRENT_BINARY_DIR}/org.kde.Akonadi.GoogleContacts.Settings.xml - ${CMAKE_CURRENT_SOURCE_DIR}/settings.h Settings) -kde4_add_executable(akonadi_googlecontacts_resource RUN_UNINSTALLED ${contactsresource_SRCS}) - -target_link_libraries(akonadi_googlecontacts_resource - ${KDEPIMLIBS_AKONADI_LIBS} - ${KDEPIMLIBS_KABC_LIBS} - ${QT_QTCORE_LIBRARY} - ${QT_QTDBUS_LIBRARY} - ${QT_QTNETWORK_LIBRARY} - ${KDE4_KDECORE_LIBS} - ${KDE4_KIO_LIBS} - kgoogle -) - -add_dependencies(akonadi_googlecontacts_resource libkgoogle) - -install(TARGETS akonadi_googlecontacts_resource ${INSTALL_TARGETS_DEFAULT_ARGS}) -install(FILES googlecontactsresource.desktop DESTINATION "${CMAKE_INSTALL_PREFIX}/share/akonadi/agents" ) diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/contactsresource.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/contactsresource.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/contactsresource.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/contactsresource.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,737 +0,0 @@ -/* - Akonadi Google - Contacts resource - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "contactsresource.h" -#include "settingsdialog.h" -#include "settings.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -using namespace Akonadi; -using namespace KGoogle; - -#define RootCollection "root" -#define MyContacts "myContacts" -#define OtherContacts "otherContacts" - -ContactsResource::ContactsResource(const QString &id): - ResourceBase(id), - m_account(0) -{ - /* Register all types we are going to use in this resource */ - qRegisterMetaType< Services::Contacts >("Contacts"); - - setNeedsNetwork(true); - setOnline(true); - - Auth *auth = Auth::instance(); - auth->init("Akonadi Google", Settings::self()->clientId(), Settings::self()->clientSecret()); - - m_gam = new KGoogle::AccessManager(); - m_photoNam = new KIO::Integration::AccessManager(this); - - connect(m_gam, SIGNAL(replyReceived(KGoogle::Reply*)), - this, SLOT(replyReceived(KGoogle::Reply*))); - - connect(m_gam, SIGNAL(error(KGoogle::Error, QString)), - this, SLOT(error(KGoogle::Error, QString))); - connect(this, SIGNAL(abortRequested()), - this, SLOT(slotAbortRequested())); - connect(this, SIGNAL(reloadConfiguration()), - this, SLOT(reloadConfig())); - connect(m_photoNam, SIGNAL(finished(QNetworkReply*)), - this, SLOT(photoRequestFinished(QNetworkReply*))); - - changeRecorder()->itemFetchScope().fetchFullPayload(true); - changeRecorder()->fetchCollection(true); - - if (!Settings::self()->account().isEmpty()) { - if (!getAccount().isNull()) { - synchronize(); - } - } -} - -ContactsResource::~ContactsResource() -{ - delete m_photoNam; - delete m_gam; -} - -void ContactsResource::aboutToQuit() -{ - cancelCurrentFetchJobs(); - slotAbortRequested(); -} - -void ContactsResource::abort() -{ - cancelTask(i18n("Aborted")); -} - -void ContactsResource::slotAbortRequested() -{ - abort(); -} - -void ContactsResource::cancelCurrentFetchJobs() -{ - Q_FOREACH(KJob *job, m_jobList) { - job->disconnect(this); //We don't want to handle any response - job->kill(); - } - m_jobList.clear(); -} - -void ContactsResource::error(Error errCode, const QString &msg) -{ - cancelTask(msg); - - if ((errCode == AuthError) || (errCode == BackendNotReady)) { - status(Broken, msg); - } - -} - -void ContactsResource::configure(WId windowId) -{ - SettingsDialog *settingsDialog = new SettingsDialog(windowId); - - if (settingsDialog->exec() == KDialog::Accepted) { - Q_EMIT configurationDialogAccepted(); - - delete settingsDialog; - - if (!getAccount().isNull()) { - synchronize(); - } - - } else { - - Q_EMIT configurationDialogRejected(); - - delete settingsDialog; - } -} - -void ContactsResource::reloadConfig() -{ - if (getAccount().isNull()) { - return; - } - - synchronize(); -} - -Account::Ptr ContactsResource::getAccount() -{ - if (!m_account.isNull()) - return m_account; - - Auth *auth = Auth::instance(); - try { - m_account = auth->getAccount(Settings::self()->account()); - } catch (KGoogle::Exception::BaseException &e) { - Q_EMIT status(Broken, e.what()); - return Account::Ptr(); - } - - return m_account; -} - - -void ContactsResource::retrieveItems(const Akonadi::Collection& collection) -{ - /* Root collection has no items */ - if (collection.remoteId() == m_collections[RootCollection].remoteId()) { - itemsRetrievalDone(); - return; - } - - ItemFetchJob *fetchJob = new ItemFetchJob(collection, this); - fetchJob->fetchScope().fetchFullPayload(true); - fetchJob->setProperty("Collection", qVariantFromValue(collection)); - connect(fetchJob, SIGNAL(finished(KJob*)), - this, SLOT(initialItemsFetchJobFinished(KJob*))); - - addFetchJob(fetchJob); - - fetchJob->start(); -} - -bool ContactsResource::retrieveItem(const Akonadi::Item& item, const QSet< QByteArray >& parts) -{ - Q_UNUSED(parts); - - if (item.mimeType() != KABC::Addressee::mimeType()) - return false; - - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return true; - } - - QUrl url(Services::Contacts::fetchContactUrl(account->accountName(), item.remoteId())); - - KGoogle::Request *request; - request = new KGoogle::Request(url, KGoogle::Request::Fetch, "Contacts", account); - request->setProperty("Item", QVariant::fromValue(item)); - - m_gam->sendRequest(request); - - return true; -} - -void ContactsResource::retrieveCollections() -{ - Akonadi::EntityDisplayAttribute *attr = new Akonadi::EntityDisplayAttribute(); - attr->setDisplayName(Settings::self()->account()); - - Collection rootCollection; - rootCollection.setName(identifier()); - rootCollection.setRemoteId(identifier()); - rootCollection.setParentCollection(Akonadi::Collection::root()); - rootCollection.setContentMimeTypes(QStringList() << Collection::mimeType() - << KABC::Addressee::mimeType()); - rootCollection.addAttribute(attr); - rootCollection.setRights(Collection::ReadOnly); - m_collections[RootCollection] = rootCollection; - - Collection::Rights rights = Collection::CanCreateItem | - Collection::CanChangeItem | - Collection::CanDeleteItem; - - attr = new Akonadi::EntityDisplayAttribute(); - attr->setDisplayName(i18n("My Contacts")); - - Collection myContacts; - myContacts.setName(i18n("My Contacts")); - myContacts.setRemoteId("http://www.google.com/m8/feeds/groups/" + Settings::self()->account() + "/base/6"); - myContacts.setParentCollection(rootCollection); - myContacts.setContentMimeTypes(QStringList() << KABC::Addressee::mimeType()); - myContacts.addAttribute(attr); - myContacts.setRights(rights); - m_collections[MyContacts] = myContacts; - - - attr = new Akonadi::EntityDisplayAttribute(); - attr->setDisplayName(i18n("Other Contacts")); - - Collection otherContacts; - otherContacts.setName(i18n("Other Contacts")); - otherContacts.setRemoteId(OtherContacts); - otherContacts.setParentCollection(rootCollection); - otherContacts.setContentMimeTypes(QStringList() << KABC::Addressee::mimeType()); - otherContacts.addAttribute(attr); - otherContacts.setRights(rights); - m_collections[OtherContacts] = otherContacts; - - collectionsRetrieved(m_collections.values()); -} - -void ContactsResource::initialItemsFetchJobFinished(KJob *job) -{ - if (job->error()) { - kDebug() << "Initial item fetch failed: " << job->errorString(); - cancelTask(i18n("Initial item fetching failed")); - return; - } - - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return; - } - - Collection collection = job->property("Collection").value< Collection >(); - - QUrl url = KGoogle::Services::Contacts::fetchAllContactsUrl(account->accountName(), true); - - QString lastSync = collection.remoteRevision(); - if (!lastSync.isEmpty()) { - KDateTime dt; - dt.setTime_t(lastSync.toInt()); - lastSync = AccessManager::dateToRFC3339String(dt); - - url.addQueryItem("updated-min", lastSync); - } - - Q_EMIT percent(0); - - FetchListJob *fetchJob = new FetchListJob(url, "Contacts", account->accountName()); - fetchJob->setProperty("Collection", qVariantFromValue(collection)); - connect(fetchJob, SIGNAL(finished(KJob*)), this, SLOT(contactListReceived(KJob*))); - connect(fetchJob, SIGNAL(percent(KJob*, ulong)), this, SLOT(emitPercent(KJob*, ulong))); - - addFetchJob(fetchJob); - - fetchJob->start(); -} - -void ContactsResource::itemAdded(const Akonadi::Item& item, const Akonadi::Collection& collection) -{ - if (!item.hasPayload< KABC::Addressee >()) - return; - - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return; - } - - KABC::Addressee addressee = item.payload< KABC::Addressee >(); - Objects::Contact contact(addressee); - - /* If the contact has been moved into My Contacts group then modify the membership */ - if (collection.remoteId() == m_collections[MyContacts].remoteId()) { - contact.addGroup(collection.remoteId()); - } - - /* If the contact has been moved to Other Contacts then remove all groups */ - if (collection.remoteId() == m_collections[OtherContacts].remoteId()) { - contact.clearGroups(); - } - - Services::Contacts service; - QByteArray data = service.objectToXML(&contact); - /* Add XML header and footer */ - data.prepend("" - ""); - data.append(""); - - KGoogle::Request *request; - request = new KGoogle::Request(Services::Contacts::createContactUrl(account->accountName()), - Request::Create, "Contacts", account); - request->setRequestData(data, "application/atom+xml"); - request->setProperty("Item", QVariant::fromValue(item)); - - m_gam->sendRequest(request); - - Q_UNUSED(collection); -} - -void ContactsResource::itemChanged(const Akonadi::Item& item, const QSet< QByteArray >& partIdentifiers) -{ - if (!item.hasPayload< KABC::Addressee >()) { - cancelTask(i18n("Invalid Payload")); - return; - } - - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return; - } - - KABC::Addressee addressee = item.payload< KABC::Addressee >(); - Objects::Contact contact(addressee); - - if (item.parentCollection().remoteId() == m_collections[MyContacts].remoteId()) { - contact.addGroup(m_collections[MyContacts].remoteId()); - } - - Services::Contacts service; - QByteArray data = service.objectToXML(&contact); - /* Add XML header and footer */ - data.prepend("" - ""); - data.append(""); - - KGoogle::Request *request; - request = new KGoogle::Request(Services::Contacts::updateContactUrl(account->accountName(), item.remoteId()), - Request::Update, "Contacts", account); - request->setRequestData(data, "application/atom+xml"); - request->setProperty("Item", QVariant::fromValue(item)); - - m_gam->sendRequest(request); - - Q_UNUSED(partIdentifiers); -} - -void ContactsResource::itemMoved(const Item& item, const Collection& collectionSource, const Collection& collectionDestination) -{ - if (!item.hasPayload< KABC::Addressee >()) { - cancelTask(i18n("Invalid payload")); - return; - } - - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return; - } - - kDebug() << "Moving contact" << item.remoteId() << "from" << collectionSource.remoteId() << "to" << collectionDestination.remoteId(); - - KABC::Addressee addressee = item.payload< KABC::Addressee >(); - Objects::Contact contact(addressee); - - if (collectionSource.remoteId() == m_collections[MyContacts].remoteId() - && collectionDestination.remoteId() == m_collections[OtherContacts].remoteId()) { - contact.removeGroup(collectionSource.remoteId()); - } else if (collectionSource.remoteId() == m_collections[OtherContacts].remoteId() - && collectionDestination.remoteId() == m_collections[MyContacts].remoteId()) { - contact.addGroup(collectionDestination.remoteId()); - } else { - cancelTask(i18n("Invalid source or destination collection")); - return; - } - - Services::Contacts service; - QByteArray data = service.objectToXML(&contact); - /* Add XML header and footer */ - data.prepend("" - ""); - data.append(""); - - KGoogle::Request *request; - request = new KGoogle::Request(Services::Contacts::updateContactUrl(account->accountName(), item.remoteId()), - Request::Update, "Contacts", account); - request->setRequestData(data, "application/atom+xml"); - request->setProperty("Item", QVariant::fromValue(item)); - - m_gam->sendRequest(request); -} - - -void ContactsResource::itemRemoved(const Akonadi::Item& item) -{ - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return; - } - - KGoogle::Request *request; - request = new KGoogle::Request(Services::Contacts::removeContactUrl(account->accountName(), item.remoteId()), - Request::Remove, "Contacts", account); - request->setProperty("Item", QVariant::fromValue(item)); - - m_gam->sendRequest(request); -} - - -void ContactsResource::replyReceived(KGoogle::Reply* reply) -{ - switch (reply->requestType()) { - case Request::Fetch: - contactReceived(reply); - break; - - case Request::Create: - contactCreated(reply); - break; - - case Request::Update: - contactUpdated(reply); - break; - - case Request::Remove: - contactRemoved(reply); - break; - - case Request::FetchAll: - case Request::Move: - case Request::Patch: - break; - } - - delete reply; -} - -void ContactsResource::contactListReceived(KJob *job) -{ - if (job->error()) { - cancelTask(i18n("Failed to retrieve contacts")); - return; - } - - Collection collection = job->property("Collection").value(); - - Item::List removed; - Item::List changed; - - FetchListJob *fetchJob = dynamic_cast< FetchListJob* >(job); - QList< KGoogle::Object* > objects = fetchJob->items(); - - Q_FOREACH(KGoogle::Object * object, objects) { - - Item item; - Objects::Contact *contact = static_cast< Objects::Contact* >(object); - - /* If we are fetching "Other Contacts" and the contact does not have - * empty member ship the skip it. For the "My Contacts" collection skip - * all contacts with empty groups. */ - if (collection.remoteId() == m_collections[OtherContacts].remoteId()) { - if (!contact->groups().isEmpty()) { - continue; - } - } else { - if (contact->groups().isEmpty()) { - continue; - } - } - - item.setRemoteId(contact->uid()); - - if (contact->deleted()) { - removed << item; - } else { - - item.setRemoteRevision(contact->etag()); - item.setMimeType(contact->mimeType()); - item.setPayload< KABC::Addressee >(KABC::Addressee(*contact)); - - changed << item; - - fetchPhoto(item); - } - } - - itemsRetrievedIncremental(changed, removed); - - collection.setRemoteRevision(QString::number(KDateTime::currentUtcDateTime().toTime_t())); - CollectionModifyJob *modifyJob = new CollectionModifyJob(collection, this); - modifyJob->setAutoDelete(true); -} - -void ContactsResource::contactReceived(KGoogle::Reply* reply) -{ - if (reply->error() != KGoogle::OK) { - cancelTask(i18n("Failed to fetch contact")); - return; - } - - QList< KGoogle::Object* > data = reply->replyData(); - if (data.length() != 1) { - kWarning() << "Server send " << data.length() << "items, which is not OK"; - cancelTask(i18n("Failed to create a contact")); - return; - } - - Objects::Contact *contact = static_cast< Objects::Contact* >(data.first()); - - Item item = reply->request()->property("Item").value< Item >(); - item.setRemoteId(contact->uid()); - item.setRemoteRevision(contact->etag()); - - if (contact->deleted()) { - itemsRetrievedIncremental(Item::List(), Item::List() << item); - } else { - item.setPayload< KABC::Addressee >(KABC::Addressee(*contact)); - item.setMimeType(contact->mimeType()); - - itemsRetrieved(Item::List() << item); - - fetchPhoto(item); - } -} - -void ContactsResource::contactCreated(KGoogle::Reply* reply) -{ - if (reply->error() != KGoogle::Created) { - cancelTask(i18n("Failed to create a contact")); - return; - } - - QList< KGoogle::Object* > data = reply->replyData(); - if (data.length() != 1) { - kWarning() << "Server send " << data.length() << "items, which is not OK"; - cancelTask(i18n("Failed to create a contact")); - return; - } - - Objects::Contact *contact = (Objects::Contact*) data.first(); - - Item item = reply->request()->property("Item").value< Item >(); - item.setRemoteId(contact->uid()); - item.setRemoteRevision(contact->etag()); - - changeCommitted(item); - - item.setPayload< KABC::Addressee >(KABC::Addressee(*contact)); - ItemModifyJob *modifyJob = new ItemModifyJob(item); - modifyJob->setAutoDelete(true); - - updatePhoto(item); -} - -void ContactsResource::contactUpdated(KGoogle::Reply* reply) -{ - if (reply->error() != KGoogle::OK) { - cancelTask(i18n("Failed to update contact")); - return; - } - - QList< KGoogle::Object* > data = reply->replyData(); - if (data.length() != 1) { - kWarning() << "Server send " << data.length() << "items, which is not OK"; - cancelTask(i18n("Failed to update a contact")); - return; - } - - Objects::Contact *contact = static_cast< Objects::Contact* >(data.first()); - - Item item = reply->request()->property("Item").value< Item >(); - item.setRemoteId(contact->uid()); - item.setRemoteRevision(contact->etag()); - - changeCommitted(item); - - updatePhoto(item); -} - -void ContactsResource::contactRemoved(KGoogle::Reply* reply) -{ - if (reply->error() != KGoogle::OK) { - cancelTask(i18n("Failed to remove contact")); - return; - } - - Item item = reply->request()->property("Item").value< Item >(); - - changeCommitted(item); -} - -void ContactsResource::photoRequestFinished(QNetworkReply* reply) -{ - /* We care only about retrieving a contact's photo. */ - if (reply->operation() == QNetworkAccessManager::GetOperation) { - QImage image; - - if (!image.loadFromData(reply->readAll(), "JPG")) - return; - - - Item item = reply->request().attribute(QNetworkRequest::User, QVariant()).value< Item >(); - - KABC::Addressee addressee = item.payload< KABC::Addressee >(); - addressee.setPhoto(KABC::Picture(image)); - item.setPayload< KABC::Addressee >(addressee); - - ItemModifyJob *modifyJob = new ItemModifyJob(item); - modifyJob->setAutoDelete(true); - } -} - -void ContactsResource::fetchPhoto(Akonadi::Item &item) -{ - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return; - } - - QString id = item.remoteId().mid(item.remoteId().lastIndexOf("/")); - - QNetworkRequest request; - request.setUrl(Services::Contacts::photoUrl(account->accountName(), id)); - request.setRawHeader("Authorization", "OAuth " + account->accessToken().toLatin1()); - request.setRawHeader("GData-Version", "3.0"); - - request.setAttribute(QNetworkRequest::User, qVariantFromValue(item)); - m_photoNam->get(request); -} - -void ContactsResource::addFetchJob(KJob* job) -{ - connect(job, SIGNAL(finished(KJob*)), this, SLOT(jobFinished(KJob*))); - m_jobList.append(job); -} - -void ContactsResource::updatePhoto(Item &item) -{ - Account::Ptr account = getAccount(); - if (account.isNull()) { - deferTask(); - return; - } - - QString id = item.remoteId().mid(item.remoteId().lastIndexOf("/")); - - KABC::Addressee addressee = item.payload< KABC::Addressee >(); - QNetworkRequest request; - request.setUrl(Services::Contacts::photoUrl(account->accountName(), id)); - request.setRawHeader("Authorization", "OAuth " + account->accessToken().toLatin1()); - request.setRawHeader("GData-Version", "3.0"); - request.setRawHeader("If-Match", "*"); - - if (!addressee.photo().isEmpty()) { - request.setHeader(QNetworkRequest::ContentTypeHeader, "image/*"); - - QImage image = addressee.photo().data(); - QByteArray ba; - QBuffer buffer(&ba); - image.save(&buffer, "JPG", 100); - - m_photoNam->put(request, ba); - } else { - m_photoNam->deleteResource(request); - } -} - -void ContactsResource::emitPercent(KJob* job, ulong progress) -{ - Q_EMIT percent(progress); - - Q_UNUSED(job) -} - -void ContactsResource::jobFinished(KJob* job) -{ - m_jobList.removeOne(job); -} - -AKONADI_RESOURCE_MAIN(ContactsResource) diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/contactsresource.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/contactsresource.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/contactsresource.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/contactsresource.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,166 +0,0 @@ -/* - Akonadi Google - Contacts Resource - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#ifndef CONTACTSRESOURCE_H -#define CONTACTSRESOURCE_H - -#include -#include -#include -#include -#include - -#include -#include - -namespace KGoogle -{ -class AccessManager; -class Reply; -class Request; -}; - -class QNetworkAccessManager; -class QNetworkReply; - -using namespace KGoogle; - -/** - * @brief An Akonadi resource for retrieving contacts from - * Google Contacts service. - * - * The resource is using asynchronous KJobs for retrieving, inserting, - * updating and removing contacts from remote address book. - * - * As each Google account can have only one address book, one resource - * for each Google accounts has to be created if user wants to have - * access to multiple addressbook accross multiple accounts. - */ -class ContactsResource: public Akonadi::ResourceBase, - public Akonadi::AgentBase::ObserverV2 -{ - Q_OBJECT - - public: - /** - * @brief Creates new resource. - * - * @param id Unique identificator of the resource assigned by Akonadi - */ - ContactsResource(const QString &id); - - ~ContactsResource(); - - using ResourceBase::synchronize; - - public Q_SLOTS: - /** - * @brief Opens configuration dialog - * - * As of now, the AuthDialog is invoked without any - * other settings dialog informing about what's going - * on or allowing to revoke the tokens. - * - * @todo Display a dialog with options to revoke tokens - * or authenticate and with an information about - * account to which the resource is authenticated - */ - virtual void configure(WId windowID); - - /** - * @brief Reloads the configuration - * - * When external applications modify the configuration of - * the resource the configuration needs to be reloaded. - * Right now what this method is is check if there is a valid - * account configured and if so, @see synchronize is called - * - * The AgentBase::reloadConfiguration signal is or should be - * connected to this slot. - */ - void reloadConfig(); - - protected Q_SLOTS: - /** - * @brief Defined list of collections. - */ - void retrieveCollections(); - - /** - * @brief Retrieves all items from remote server. - * - * @todo Don't fetch all items every time from remote server, - * ask only for items updated since last synchronization. - */ - void retrieveItems(const Akonadi::Collection& collection); - - /** - * @brief Retrieves single contactJobFinished - */ - bool retrieveItem(const Akonadi::Item& item, const QSet< QByteArray >& parts); - - void itemRemoved(const Akonadi::Item& item); - void itemAdded(const Akonadi::Item& item, const Akonadi::Collection& collection); - void itemChanged(const Akonadi::Item& item, const QSet< QByteArray >& partIdentifiers); - void itemMoved(const Akonadi::Item& item, const Akonadi::Collection& collectionSource, - const Akonadi::Collection& collectionDestination); - - protected: - void aboutToQuit(); - - private Q_SLOTS: - void error(KGoogle::Error errCode, const QString &msg); - - void slotAbortRequested(); - void cancelCurrentFetchJobs(); - - void initialItemsFetchJobFinished(KJob *job); - void contactListReceived(KJob *job); - - void photoRequestFinished(QNetworkReply *reply); - - void replyReceived(KGoogle::Reply *reply); - - void contactReceived(KGoogle::Reply *reply); - void contactUpdated(KGoogle::Reply *reply); - void contactCreated(KGoogle::Reply *reply); - void contactRemoved(KGoogle::Reply *reply); - - void emitPercent(KJob *job, ulong progress); - - void jobFinished(KJob *job); - - private: - void abort(); - - void updatePhoto(Akonadi::Item &item); - void fetchPhoto(Akonadi::Item &item); - void addFetchJob(KJob *job); - - Account::Ptr getAccount(); - - KGoogle::Account::Ptr m_account; - - KGoogle::AccessManager *m_gam; - QNetworkAccessManager *m_photoNam; - QMap< QString, Akonadi::Collection > m_collections; - QList m_jobList; -}; - -#endif // CONTACTSRESOURCE_H diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/googlecontactsresource.desktop akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/googlecontactsresource.desktop --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/googlecontactsresource.desktop 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/googlecontactsresource.desktop 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -[Desktop Entry] -Name=Google Contacts -Name[cs]=Kontakty Google -Name[da]=Google-kontakter -Name[de]=Google-Kontakte -Name[es]=Contactos de Google -Name[et]=Google'i kontaktid -Name[fr]=Google Contacts -Name[it]=Contatti di Google -Name[km]=ទំនាក់ទំនង​ហ្គូហ្គល -Name[nds]=Google-Kontakten -Name[nl]=Google contactpersonen -Name[pl]=Kontakty Google -Name[pt]=Contactos do Google -Name[pt_BR]=Contatos do Google -Name[sv]=Google-kontakter -Name[uk]=Контакти Google -Name[x-test]=xxGoogle Contactsxx -Comment=Access your Google Contacts from KDE -Comment[da]=Tilgå dine Google-kontakter fra KDE -Comment[de]=Greifen Sie von KDE auf Ihre Google-Kontakte zu -Comment[es]=Acceda a sus contactos de Google desde KDE -Comment[et]=Oma Google'i kontaktide kasutamine otse KDE-st -Comment[fr]=Accédez à vos contacts Google depuis KDE -Comment[it]=Accedi ai tuoi contatti di Google da KDE -Comment[km]=ចូល​ដំណើរការ​ទំនាក់ទំនង​ហ្គូហ្គល​របស់​អ្នក​ពី KDE -Comment[nl]=Heb toegang tot uw Google contactpersonen vanuit KDE -Comment[pl]=Uzyskaj dostęp do Kontaktów Google z KDE -Comment[pt]=Aceda aos seus contactos da Google a partir do KDE -Comment[pt_BR]=Acesse seus contatos da Google a partir do KDE -Comment[sv]=Kom åt dina Google-kontakter från KDE -Comment[uk]=Доступ до ваших записів контактів Google з KDE -Comment[x-test]=xxAccess your Google Contacts from KDExx -Type=AkonadiResource -Exec=akonadi_googlecontacts_resource -X-Akonadi-MimeTypes=text/directory, -X-Akonadi-Capabilities=Resource -X-Akonadi-Identifier=akonadi_googlecontacts_resource diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/settingsbase.kcfg akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/settingsbase.kcfg --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/settingsbase.kcfg 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/settingsbase.kcfg 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ - - - - - - - - true - - - 30 - - - diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/settingsbase.kcfgc akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/settingsbase.kcfgc --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/settingsbase.kcfgc 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/settingsbase.kcfgc 1970-01-01 00:00:00.000000000 +0000 @@ -1,7 +0,0 @@ -File=settingsbase.kcfg -ClassName=SettingsBase -Mutators=true -ItemAccessors=true -SetUserTexts=true -Singleton=false -GlobalEnums=true \ No newline at end of file diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/settings.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/settings.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/settings.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/settings.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -/* - Akonadi Google - Contacts Resource - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "settings.h" -#include "settingsbase.h" -#include "settingsadaptor.h" - -#include -#include - -#include - -class SettingsHelper -{ - public: - SettingsHelper(): q(0) {}; - ~SettingsHelper() { - delete q; - q = 0; - } - - Settings *q; -}; - -K_GLOBAL_STATIC(SettingsHelper, s_globalSettings) - -Settings::Settings() -{ - Q_ASSERT(!s_globalSettings->q); - s_globalSettings->q = this; - - new SettingsAdaptor(this); - QDBusConnection::sessionBus().registerObject(QLatin1String("/Settings"), this, - QDBusConnection::ExportAdaptors | QDBusConnection::ExportScriptableContents); -} - -Settings* Settings::self() -{ - if (!s_globalSettings->q) { - new Settings; - s_globalSettings->q->readConfig(); - } - - return s_globalSettings->q; - -} - -QString Settings::clientId() const -{ - return "554041944266.apps.googleusercontent.com"; -} - -QString Settings::clientSecret() const -{ - return "mdT1DjzohxN3npUUzkENT0gO"; -} - -void Settings::setWindowId(WId id) -{ - m_winId = id; -} - -void Settings::setResourceId(const QString &resourceIdentificator) -{ - m_resourceId = resourceIdentificator; -} diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/settingsdialog.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/settingsdialog.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/settingsdialog.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/settingsdialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,148 +0,0 @@ -/* - Akonadi Google - Contacts Resource - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include -#include - -#include "settingsdialog.h" -#include "ui_settingsdialog.h" -#include "settings.h" - -#include -#include - - -using namespace KGoogle; - -enum { - KGoogleObjectRole = Qt::UserRole, - ObjectUIDRole -}; - -SettingsDialog::SettingsDialog(WId windowId, QWidget *parent): - KDialog(parent), - m_windowId(windowId) -{ - KWindowSystem::setMainWindow(this, windowId); - - qRegisterMetaType("Contacts"); - - this->setButtons(Ok | Cancel); - - m_mainWidget = new QWidget(); - m_ui = new ::Ui::SettingsDialog(); - m_ui->setupUi(m_mainWidget); - setMainWidget(m_mainWidget); - - m_ui->addAccountBtn->setIcon(QIcon::fromTheme("list-add-user")); - m_ui->removeAccountBtn->setIcon(QIcon::fromTheme("list-remove-user")); - - connect(this, SIGNAL(accepted()), - this, SLOT(saveSettings())); - - connect(m_ui->addAccountBtn, SIGNAL(clicked(bool)), - this, SLOT(addAccountClicked())); - connect(m_ui->removeAccountBtn, SIGNAL(clicked(bool)), - this, SLOT(removeAccountClicked())); - - KGoogle::Auth *auth = KGoogle::Auth::instance(); - connect(auth, SIGNAL(authenticated(KGoogle::Account::Ptr&)), - this, SLOT(reloadAccounts())); - - reloadAccounts(); -} - -SettingsDialog::~SettingsDialog() -{ - delete m_ui; - delete m_mainWidget; -} - -void SettingsDialog::saveSettings() -{ - Settings::self()->setAccount(m_ui->accountsCombo->currentText()); - Settings::self()->writeConfig(); -} - - -void SettingsDialog::error(KGoogle::Error errCode, const QString &msg) -{ - if (errCode == KGoogle::OK) - return; - - KMessageBox::error(this, msg, i18n("An error occurred")); - - m_ui->accountsBox->setEnabled(true); -} - - -void SettingsDialog::reloadAccounts() -{ - m_ui->accountsCombo->reload(); - - QString accName = Settings::self()->account(); - int index = -1; - - if (!accName.isEmpty()) - index = m_ui->accountsCombo->findText(accName); - - if (index > -1) { - m_ui->accountsCombo->setCurrentIndex(index); - } -} - -void SettingsDialog::addAccountClicked() -{ - KGoogle::Auth *auth = KGoogle::Auth::instance(); - - KGoogle::Account::Ptr account(new KGoogle::Account()); - account->addScope(Services::Contacts::ScopeUrl); - - try { - auth->authenticate(account, true); - } catch (KGoogle::Exception::BaseException &e) { - KMessageBox::error(this, e.what()); - } -} - -void SettingsDialog::removeAccountClicked() -{ - KGoogle::Account::Ptr account = m_ui->accountsCombo->currentAccount(); - - if (account.isNull()) - return; - - if (KMessageBox::warningYesNo(this, - i18n("Do you really want to revoke access to account %1?" - "
This will revoke access to all application using this account!", account->accountName()), - i18n("Revoke Access?"), - KStandardGuiItem::yes(), KStandardGuiItem::no(), QString(), KMessageBox::Dangerous) != KMessageBox::Yes) { - - return; - } - - KGoogle::Auth *auth = KGoogle::Auth::instance(); - - try { - auth->revoke(account); - } catch (KGoogle::Exception::BaseException &e) { - KMessageBox::error(this, e.what()); - } - - reloadAccounts(); -} diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/settingsdialog.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/settingsdialog.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/settingsdialog.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/settingsdialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,57 +0,0 @@ -/* - Akonadi Google - Calendar Resource - Copyright (C) 2011, 2012 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#ifndef SETTINGSDIALOG_H -#define SETTINGSDIALOG_H - -#include - -#include - -namespace Ui -{ -class SettingsDialog; -} - -class QTreeWidgetItem; - -class SettingsDialog : public KDialog -{ - Q_OBJECT - public: - SettingsDialog(WId windowId, QWidget *parent = 0); - ~SettingsDialog(); - - private Q_SLOTS: - void addAccountClicked(); - void removeAccountClicked(); - void reloadAccounts(); - - void error(KGoogle::Error errCode, const QString &msg); - void saveSettings(); - - private: - Ui::SettingsDialog *m_ui; - QWidget *m_mainWidget; - - WId m_windowId; - -}; - -#endif // SETTINGSDIALOG_H diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/settings.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/settings.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/settings.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/settings.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,55 +0,0 @@ -/* - Akonadi Google - Contacts Resource - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#ifndef SETTINGS_H -#define SETTINGS_H - -#include "settingsbase.h" - -#include - -/** - * @brief Settings object - * - * Provides read-only access to application clientId and - * clientSecret and read-write access to accessToken and - * refreshToken. - */ -class Settings: public SettingsBase -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "org.kde.Akonadi.GoogleContacts.ExtendedSettings") - public: - Settings(); - void setWindowId(WId id); - void setResourceId(const QString &resourceIdentifier); - static Settings* self(); - - QString appId() const; - - QString clientId() const; - QString clientSecret() const; - - private: - WId m_winId; - QString m_resourceId; - -}; - -#endif // SETTINGS_H diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/ui/groupeditor.ui akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/ui/groupeditor.ui --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/ui/groupeditor.ui 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/ui/groupeditor.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,31 +0,0 @@ - - - GroupEditor - - - - 0 - 0 - 400 - 30 - - - - Group Editor - - - - - - Group Name: - - - - - - - - - - - diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/ui/settingsdialog.ui akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/ui/settingsdialog.ui --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/contacts/ui/settingsdialog.ui 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/contacts/ui/settingsdialog.ui 1970-01-01 00:00:00.000000000 +0000 @@ -1,61 +0,0 @@ - - - SettingsDialog - - - - 0 - 0 - 470 - 68 - - - - Contacts Resource Settings - - - - - - Account - - - - - - - 0 - 0 - - - - - - - - Add - - - - - - - Remove - - - - - - - - - - - KGoogle::Ui::AccountsCombo - QComboBox -
libkgoogle/ui/accountscombo.h
-
-
- - -
diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/debian/bzr-builder.manifest akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/debian/bzr-builder.manifest --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/debian/bzr-builder.manifest 2012-05-22 19:00:53.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/debian/bzr-builder.manifest 2012-06-16 02:20:59.000000000 +0000 @@ -1,3 +1,3 @@ -# bzr-builder format 0.3 deb-version 1:{debupstream}-0ubuntu1+201205221900-SNAPSHOT-176 -lp:~benoitg/akonadigoogle/trunk-pre-kdepim-runtime revid:git-v1:6450e23baa5921d1579076febfca3ed57a6b4459 +# bzr-builder format 0.3 deb-version 1:{debupstream}-0ubuntu1+201206160220-SNAPSHOT-193 +lp:~benoitg/akonadigoogle/0.3 revid:git-v1:f18d699d9ef7ceceff06c2bb72fc00f34811c503 nest-part packaging lp:~benoitg/akonadigoogle/akonadigoogle.upstream_packaging debian debian revid:benoitg@coeus.ca-20120508141245-0tzxlrjsw1ltvksb diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/debian/changelog akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/debian/changelog --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/debian/changelog 2012-05-22 19:00:53.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/debian/changelog 2012-06-16 02:20:59.000000000 +0000 @@ -1,8 +1,8 @@ -akonadi-google (1:0.3.1-0ubuntu1+201205221900-SNAPSHOT-176~oneiric1) oneiric; urgency=low +akonadi-google (1:0.3.1-0ubuntu1+201206160220-SNAPSHOT-193~oneiric1) precise; urgency=low * Auto build. - -- Benoit Grégoire Tue, 22 May 2012 19:00:53 +0000 + -- Benoit Grégoire Sat, 16 Jun 2012 02:20:59 +0000 akonadi-google (1:0.3.1-ubuntu1) precise; urgency=low diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/accessmanager.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/accessmanager.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/accessmanager.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/accessmanager.cpp 2012-06-16 02:20:58.000000000 +0000 @@ -27,9 +27,12 @@ #include #include -#include -#include +#include +#include #include +#include + +static const KCatalogLoader loader("libkgoogle"); int debugArea() { @@ -42,8 +45,8 @@ AccessManager::AccessManager(): d_ptr(new AccessManagerPrivate(this)) { - connect(Auth::instance(), SIGNAL(error(KGoogle::Error, QString)), - this, SIGNAL(error(KGoogle::Error, QString))); + connect(Auth::instance(), SIGNAL(error(KGoogle::Error,QString)), + this, SIGNAL(error(KGoogle::Error,QString))); } AccessManager::~AccessManager() @@ -168,7 +171,7 @@ return result + QLatin1Char('Z'); if (datetime.timeType() == KDateTime::ClockTime) tz = KSystemTimeZones::local(); - tzcolon = ":"; + tzcolon = ':'; // Return the string with UTC offset ±hhmm appended if (datetime.timeType() == KDateTime::OffsetFromUTC || datetime.timeType() == KDateTime::TimeZone || tz.isValid()) { diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/accessmanager.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/accessmanager.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/accessmanager.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/accessmanager.h 2012-06-16 02:20:58.000000000 +0000 @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/accessmanager_p.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/accessmanager_p.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/accessmanager_p.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/accessmanager_p.cpp 2012-06-16 02:20:58.000000000 +0000 @@ -31,7 +31,7 @@ #include #include -#include +#include #define RequestAttribute QNetworkRequest::User @@ -68,9 +68,12 @@ QByteArray rawData = reply->readAll(); + /* Delete the reply after we leave this method */ + reply->deleteLater(); + #ifdef DEBUG_RAWDATA QStringList headers; - Q_FOREACH(QString str, reply->rawHeaderList()) { + Q_FOREACH(const QString &str, reply->rawHeaderList()) { headers << str + ": " + reply->rawHeader(str.toLatin1()); } kDebug() << headers; @@ -93,7 +96,7 @@ * as an error. */ if (!reply->rawHeaderList().isEmpty()) { QString status = reply->rawHeaderList().first(); - if (status.startsWith("HTTP/1.1 401")) + if (status.startsWith(QLatin1String("HTTP/1.1 401"))) replyCode = KGoogle::Unauthorized; } } @@ -166,55 +169,69 @@ /* Don't emit error here, user should not know that we need to re-negotiate tokens again. */ return; - case KGoogle::Forbidden: + case KGoogle::Forbidden: { kWarning() << "Requested resource is forbidden."; kWarning() << rawData; - Q_EMIT q->error(KGoogle::Forbidden, i18n("Requested resource is forbidden.\n\nGoogle replied '%1'", QString(rawData))); - Q_EMIT request->error(KGoogle::Forbidden, i18n("Requested resource is forbidden.\n\nGoogle replied '%1'", QString(rawData))); + QString msg = parseErrorMessage(rawData); + Q_EMIT q->error(KGoogle::Forbidden, i18n("Requested resource is forbidden.\n\nGoogle replied '%1'", msg)); + Q_EMIT request->error(KGoogle::Forbidden, i18n("Requested resource is forbidden.\n\nGoogle replied '%1'", msg)); return; + } - case KGoogle::NotFound: + case KGoogle::NotFound: { kWarning() << "Requested resource does not exist"; kWarning() << rawData; - Q_EMIT q->error(KGoogle::NotFound, i18n("Requested resource does not exist.\n\nGoogle replied '%1'", QString(rawData))); - Q_EMIT request->error(KGoogle::NotFound, i18n("Requested resource does not exist.\n\nGoogle replied '%1'", QString(rawData))); + QString msg = parseErrorMessage(rawData); + Q_EMIT q->error(KGoogle::NotFound, i18n("Requested resource does not exist.\n\nGoogle replied '%1'", msg)); + Q_EMIT request->error(KGoogle::NotFound, i18n("Requested resource does not exist.\n\nGoogle replied '%1'", msg)); return; + } - case KGoogle::Conflict: + case KGoogle::Conflict: { kWarning() << "Conflict. Remote resource is newer then local."; kWarning() << rawData; - Q_EMIT q->error(KGoogle::Conflict, i18n("Conflict. Remote resource is newer then local.\n\nGoogle replied '%1'", QString(rawData))); - Q_EMIT request->error(KGoogle::Conflict, i18n("Conflict. Remote resource is newer then local.\n\nGoogle replied '%1'", QString(rawData))); + QString msg = parseErrorMessage(rawData); + Q_EMIT q->error(KGoogle::Conflict, i18n("Conflict. Remote resource is newer then local.\n\nGoogle replied '%1'", msg)); + Q_EMIT request->error(KGoogle::Conflict, i18n("Conflict. Remote resource is newer then local.\n\nGoogle replied '%1'", msg)); return; + } - case KGoogle::Gone: + case KGoogle::Gone: { kWarning() << "Requested resource does not exist anymore."; kWarning() << rawData; - Q_EMIT q->error(KGoogle::Gone, i18n("Requested resource does not exist anymore.\n\nGoogle replied '%1'", QString(rawData))); - Q_EMIT request->error(KGoogle::Gone, i18n("Requested resource does not exist anymore.\n\nGoogle replied '%1'", QString(rawData))); + QString msg = parseErrorMessage(rawData); + Q_EMIT q->error(KGoogle::Gone, i18n("Requested resource does not exist anymore.\n\nGoogle replied '%1'", msg)); + Q_EMIT request->error(KGoogle::Gone, i18n("Requested resource does not exist anymore.\n\nGoogle replied '%1'", msg)); return; + } - case KGoogle::InternalError: + case KGoogle::InternalError: { kWarning() << "Internal server error."; kWarning() << rawData; - Q_EMIT q->error(KGoogle::InternalError, i18n("Internal server error. Try again later.\n\nGoogle replied '%1'", QString(rawData))); - Q_EMIT request->error(KGoogle::InternalError, i18n("Internal server error. Try again later.\n\nGoogle replied '%1'", QString(rawData))); + QString msg = parseErrorMessage(rawData); + Q_EMIT q->error(KGoogle::InternalError, i18n("Internal server error. Try again later.\n\nGoogle replied '%1'", msg)); + Q_EMIT request->error(KGoogle::InternalError, i18n("Internal server error. Try again later.\n\nGoogle replied '%1'", msg)); return; + } - case KGoogle::QuotaExceeded: + case KGoogle::QuotaExceeded: { kWarning() << "User quota exceeded."; kWarning() << rawData; - Q_EMIT q->error(KGoogle::QuotaExceeded, i18n("User quota exceeded. Try again later.\n\nGoogle replied '%1'", QString(rawData))); - Q_EMIT request->error(KGoogle::QuotaExceeded, i18n("User quota exceeded. Try again later.\n\nGoogle replied '%1'", QString(rawData))); + QString msg = parseErrorMessage(rawData); + Q_EMIT q->error(KGoogle::QuotaExceeded, i18n("User quota exceeded. Try again later.\n\nGoogle replied '%1'", msg)); + Q_EMIT request->error(KGoogle::QuotaExceeded, i18n("User quota exceeded. Try again later.\n\nGoogle replied '%1'", msg)); return; + } - default: /** Something went wrong, there's nothing we can do about it */ + default:{ /** Something went wrong, there's nothing we can do about it */ kWarning() << "Unknown error" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt() << ", Google replied '" << rawData << "'"; - Q_EMIT q->error(KGoogle::UnknownError, i18n("Unknown error.\n\nGoogle replied '%1'", QString(rawData))); - Q_EMIT request->error(KGoogle::UnknownError, QString(rawData)); + QString msg = parseErrorMessage(rawData); + Q_EMIT q->error(KGoogle::UnknownError, i18n("Unknown error.\n\nGoogle replied '%1'", msg)); + Q_EMIT request->error(KGoogle::UnknownError, msg); return; } + } QList< KGoogle::Object* > replyData; @@ -240,6 +257,9 @@ } else { kDebug() << "Unknown reply content type!"; + Q_EMIT q->error(KGoogle::InvalidResponse, i18n("Unknown reply content type!")); + Q_EMIT request->error(KGoogle::InvalidResponse, i18n("Unknown reply content type!")); + return; } processedItems = feedData.startIndex; @@ -325,7 +345,7 @@ #ifdef DEBUG_RAWDATA QStringList headers; - Q_FOREACH(QString str, nr.rawHeaderList()) { + Q_FOREACH(const QString &str, nr.rawHeaderList()) { headers << str + ": " + nr.rawHeader(str.toLatin1()); } kDebug() << headers; @@ -384,3 +404,30 @@ while (!cache.isEmpty() && cacheSemaphore->available()) nam_sendRequest(cache.dequeue()); } + +QString AccessManagerPrivate::parseErrorMessage(const QByteArray &json) const +{ + QJson::Parser parser; + bool ok; + + QVariant data = parser.parse(json, &ok); + if (ok) { + QString message; + QVariantMap map = data.toMap(); + + if (map.contains("error")) { + map = map["error"].toMap(); + } + + if (map.contains("message")) { + message.append(map["message"].toString()); + } else { + message = QString(json); + } + + return message; + + } else { + return QString(json); + } +} diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/accessmanager_p.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/accessmanager_p.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/accessmanager_p.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/accessmanager_p.h 2012-06-16 02:20:58.000000000 +0000 @@ -16,8 +16,8 @@ along with this program. If not, see . */ -#ifndef LIBKGOOGLE_ACCESSMANAGER_P_H_ -#define LIBKGOOGLE_ACCESSMANAGER_P_H_ +#ifndef LIBKGOOGLE_ACCESSMANAGER_P_H +#define LIBKGOOGLE_ACCESSMANAGER_P_H #include #include @@ -60,10 +60,12 @@ void submitCache(); private: + QString parseErrorMessage(const QByteArray &json) const; + AccessManager* const q_ptr; Q_DECLARE_PUBLIC(AccessManager) }; } -#endif /* LIBKGOOGLE_ACCESSMANAGER_P_H_ */ \ No newline at end of file +#endif /* LIBKGOOGLE_ACCESSMANAGER_P_H */ diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/account.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/account.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/account.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/account.h 2012-06-16 02:20:58.000000000 +0000 @@ -73,9 +73,9 @@ * @param refreshToken Refres token * @param scopes List of scopes */ - Account(const QString &account, const QString &accessToken = QString(), - const QString &refreshToken = QString(), - const QList< QUrl > &scopes = QList< QUrl >()); + explicit Account(const QString &account, const QString &accessToken = QString(), + const QString &refreshToken = QString(), + const QList< QUrl > &scopes = QList< QUrl >()); Account(const Account &other); @@ -160,7 +160,7 @@ * * KGoogle::Auth reads this attribute when Account is passed to * KGoogle::Auth::authenticate() to determine whether completely new - * process of authentication is needed, or wheter just refreshing tokens + * process of authentication is needed, or whether just refreshing tokens * is enough. * * When m_scopesChanged is TRUE and KGoogle::Auth::authenticate() successffuly @@ -172,7 +172,7 @@ } /* namespace KGoogle */ -Q_DECLARE_METATYPE(KGoogle::Account::Ptr); -Q_DECLARE_METATYPE(KGoogle::Account*); +Q_DECLARE_METATYPE(KGoogle::Account::Ptr) +Q_DECLARE_METATYPE(KGoogle::Account*) #endif // LIBKGOOGLE_ACCOUNT_H diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/auth.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/auth.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/auth.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/auth.cpp 2012-06-16 02:20:58.000000000 +0000 @@ -19,12 +19,14 @@ #include "auth.h" #include "auth_p.h" - #include "common.h" #include "services/accountinfo.h" +#include "ui/authwidget.h" -#include -#include +#include +#include +#include +#include #include #include @@ -139,7 +141,7 @@ d->kwallet->setFolder(d->kwalletFolder); QStringList list = d->kwallet->entryList(); - Q_FOREACH(QString accName, list) { + Q_FOREACH(const QString &accName, list) { QMap< QString, QString > map; d->kwallet->readMap(accName, map); @@ -218,32 +220,43 @@ { Q_D(Auth); - if (!d->initKWallet()) { - return; - } + AuthWidget *widget; + KDialog *dlg; - if (account.isNull()) { - throw Exception::InvalidAccount(); - return; - } + widget = d->authenticate(account, autoSave); - if (account->refreshToken().isEmpty() || (account->m_scopesChanged == true)) { - - account->addScope(Services::AccountInfo::EmailScopeUrl); - d->fullAuthentication(account, autoSave); + if (widget) { + dlg = new KDialog(); + dlg->setModal(true); + KWindowSystem::setMainWindow(dlg, KWindowSystem::activeWindow()); + + dlg->setMainWidget(widget); + connect(widget, SIGNAL(error(KGoogle::Error,QString)), + this, SIGNAL(error(KGoogle::Error,QString))); + connect(dlg, SIGNAL(cancelClicked()), dlg, SLOT(delayedDestruct())); + + if (d->dialogAutoClose) { + connect(widget, SIGNAL(authenticated(KGoogle::Account::Ptr&)), + dlg, SLOT(delayedDestruct())); + connect(widget, SIGNAL(error(KGoogle::Error,QString)), + dlg, SLOT(delayedDestruct())); + } - } else { + dlg->show(); + dlg->setButtons(KDialog::Cancel); + widget->authenticate(); + } +} - if (account->accountName().isEmpty()) { - throw Exception::InvalidAccount(); - return; - } - d->refreshTokens(account, autoSave); +KGoogle::AuthWidget* Auth::authenticateWithWidget(Account::Ptr& account, bool autoSave) +{ + Q_D(Auth); - } + return d->authenticate(account, autoSave); } + bool Auth::revoke(Account::Ptr &account) { Q_D(Auth); @@ -302,6 +315,6 @@ void Auth::clearCredentials() { Q_D(Auth); - d->username = QString(); - d->password = QString(); -} \ No newline at end of file + d->username.clear(); + d->password.clear(); +} diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/authdialog.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/authdialog.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/authdialog.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/authdialog.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,295 +0,0 @@ -/* - Akonadi Google Resource - OAuth authentication dialog - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#include "authdialog.h" - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "accessmanager.h" -#include "auth.h" -#include "reply.h" -#include "request.h" -#include "services/accountinfo.h" -#include "objects/accountinfo.h" - -extern int debugArea(); - -/****************** Private implementation *****************/ - -void AuthDialog::emitError(const KGoogle::Error errCode, const QString& msg) -{ - m_label->setVisible(true); - m_webiew->setVisible(false); - m_progressbar->setVisible(false); - - m_label->setText("" + msg + ""); - - Q_EMIT error(errCode, msg); -} - - -void AuthDialog::webviewUrlChanged(const QUrl &url) -{ - QString token, verifier; - - /* Access token here - hide browser and tell user to wait until we - * finish the authentication process ourselves */ - if (url.host() == "accounts.google.com" && url.path() == "/o/oauth2/approval") { - m_webiew->setVisible(false); - m_progressbar->setVisible(false); - m_label->setVisible(true); - } -} - -void AuthDialog::webviewFinished() -{ - QUrl url = m_webiew->url(); - - if (url.host() == "accounts.google.com" && url.path() == "/ServiceLogin") { - if (m_username.isEmpty() && m_password.isEmpty()) { - return; - } - - QWebFrame *frame = m_webiew->page()->mainFrame(); - if (!m_username.isEmpty()) { - QWebElement email = frame->findFirstElement("input#Email"); - if (!email.isNull()) { - email.setAttribute("value", m_username); - } - } - - if (!m_password.isEmpty()) { - QWebElement passd = frame->findFirstElement("input#Passwd"); - if (!passd.isNull()) { - passd.setAttribute("value", m_password); - } - } - - return; - } - - if (url.host() == "accounts.google.com" && url.path() == "/o/oauth2/approval") { - QWebElement el = m_webiew->page()->mainFrame()->findFirstElement("textarea"); - if (el.isNull()) { - emitError(KGoogle::AuthError, i18n("Parsing token page failed.")); - return; - } - - QString token = el.toInnerXml(); - if (token.isEmpty()) { - emitError(KGoogle::AuthError, i18n("Failed to obtain token.")); - return; - } - - QNetworkAccessManager *nam = new KIO::Integration::AccessManager(this); - QNetworkRequest request; - - connect(nam, SIGNAL(finished(QNetworkReply*)), - this, SLOT(networkRequestFinished(QNetworkReply*))); - connect(nam, SIGNAL(finished(QNetworkReply*)), - nam, SLOT(deleteLater())); - - request.setUrl(QUrl("https://accounts.google.com/o/oauth2/token")); - request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); - - QUrl params; - params.addQueryItem("client_id", KGoogle::Auth::instance()->apiKey()); - params.addQueryItem("client_secret", KGoogle::Auth::instance()->apiSecret()); - params.addQueryItem("code", token); - params.addQueryItem("redirect_uri", "urn:ietf:wg:oauth:2.0:oob"); - params.addQueryItem("grant_type", "authorization_code"); - -#ifdef DEBUG_RAWDATA - kDebug() << "Authorizing token:" << params; -#endif - - nam->post(request, params.encodedQuery()); - } -} - -void AuthDialog::networkRequestFinished(QNetworkReply* reply) -{ - if (reply->error() != QNetworkReply::NoError) { - emitError(KGoogle::AuthError, i18n("Authentization failed:
%1", reply->errorString())); - return; - } - - QJson::Parser parser; - bool ok; - - QVariantMap parsed_data = parser.parse(reply->readAll(), &ok).toMap(); - if (!ok) { - emitError(KGoogle::AuthError, i18n("Failed to parse server response.")); - return; - } - -#ifdef DEBUG_RAWDATA - kDebug() << "Retrieved new tokens pair:" << parsed_data; -#endif - - m_account->setAccessToken(parsed_data["access_token"].toString()); - m_account->setRefreshToken(parsed_data["refresh_token"].toString()); - - KGoogle::AccessManager *gam = new KGoogle::AccessManager; - connect(gam, SIGNAL(replyReceived(KGoogle::Reply*)), - this, SLOT(accountInfoReceived(KGoogle::Reply*))); - connect(gam, SIGNAL(replyReceived(KGoogle::Reply*)), - gam, SLOT(deleteLater())); - - KGoogle::Request *request; - request = new KGoogle::Request(KGoogle::Services::AccountInfo::fetchUrl(), - KGoogle::Request::Fetch, "AccountInfo", m_account); - - gam->sendRequest(request); -} - -void AuthDialog::accountInfoReceived(KGoogle::Reply* reply) -{ - if (reply->error() != KGoogle::OK) { - emitError(reply->error(), reply->errorString()); - return; - } - - QList< KGoogle::Object* > data = reply->replyData(); - KGoogle::Objects::AccountInfo *accountInfo = static_cast< KGoogle::Objects::AccountInfo* >(data.first()); - - m_account->setAccountName(accountInfo->email()); - - delete reply; - - Q_EMIT authenticated(m_account); - accept(); -} - - -/********************* Public implementation ***************/ - -AuthDialog::AuthDialog(WId windowId): - KDialog() -{ - KWindowSystem::setMainWindow(this, windowId); - - qRegisterMetaType< KGoogle::Services::AccountInfo >("AccountInfo"); - - setModal(true); - - m_widget = new QWidget(this); - setMainWidget(m_widget); - - m_vbox = new QVBoxLayout(m_widget); - m_widget->setLayout(m_vbox); - - m_label = new QLabel(m_widget); - m_label->setText("" + i18n("Authorizing token. This should take just a moment...") + ""); - m_label->setWordWrap(true); - m_label->setAlignment(Qt::AlignCenter); - m_label->setVisible(false); - m_vbox->addWidget(m_label); - - m_progressbar = new QProgressBar(m_widget); - m_progressbar->setMinimum(0); - m_progressbar->setMaximum(100); - m_progressbar->setValue(0); - m_vbox->addWidget(m_progressbar); - - m_webiew = new QWebView(m_widget); - m_vbox->addWidget(m_webiew); - connect(m_webiew, SIGNAL(loadProgress(int)), - m_progressbar, SLOT(setValue(int))); - connect(m_webiew, SIGNAL(urlChanged(QUrl)), - this, SLOT(webviewUrlChanged(QUrl))); - connect(m_webiew, SIGNAL(loadFinished(bool)), - this, SLOT(webviewFinished())); - - m_hbox = new QHBoxLayout(m_widget); - m_vbox->addLayout(m_hbox); - - setButtons(KDialog::Cancel); -} - -AuthDialog::~AuthDialog() -{ - delete m_label; - delete m_progressbar; - delete m_webiew; - delete m_hbox; - delete m_vbox; - delete m_widget; -} - -void AuthDialog::authenticate(KGoogle::Account::Ptr &account) -{ - - if (account.isNull() || account->scopes().isEmpty()) { - throw KGoogle::Exception::InvalidAccount(); - return; - } - - m_account = account; - - QStringList scopes; - Q_FOREACH(const QUrl & scope, account->scopes()) { - scopes << scope.toString(); - } - - QUrl url("https://accounts.google.com/o/oauth2/auth"); - url.addQueryItem("client_id", KGoogle::Auth::instance()->apiKey()); - url.addQueryItem("redirect_uri", "urn:ietf:wg:oauth:2.0:oob"); - url.addQueryItem("scope", scopes.join(" ")); - url.addQueryItem("response_type", "code"); - -#ifdef DEBUG_RAWDATA - kDebug() << "Requesting new token:" << url; -#endif - - m_webiew->setUrl(url); -} - -void AuthDialog::setUsername(const QString& username) -{ - m_username = username; -} - -void AuthDialog::setPassword(const QString& password) -{ - m_password = password; -} - -void AuthDialog::clearCredentials() -{ - m_username = QString(); - m_password = QString(); -} \ No newline at end of file diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/authdialog.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/authdialog.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/authdialog.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/authdialog.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -/* - - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#ifndef AUTHDIALOG_H -#define AUTHDIALOG_H - -#include -#include - -#include -#include - -class QNetworkReply; -class QHBoxLayout; -class QVBoxLayout; -class QProgressBar; -class QLabel; -class QWebView; -class KWebView; - -namespace KGoogle -{ - -class Reply; - -}; - - -/** - * Dialog for authentication with Google services. - * - * The dialog opens Google login page in embedded webivew, - * asking user to login and confirm access of this application - * to some services. - * After that the webview is hidden and the dialog exchanges some tokens - * for access and refresh tokens. - * The access token is then used for authenticating any request on Google - * services, the refresh token is used to refresh expired access token. - * - * This dialog is not (for now) part of public API, thus it's not in the KGoogle - * namespace and neither is this header installed. - */ -class LIBKGOOGLE_EXPORT AuthDialog: public KDialog -{ - Q_OBJECT - - public: - /** - * Creates the dialog - * - * @param windowId ID of parent window - */ - AuthDialog(WId windowId); - - virtual ~AuthDialog(); - - /** - * Starts the authentication process of \p account. When finished - * the authenticated() signal will be emitted with the same instance - * of \p account and with tokens and name filled. - * - * Throws KGoogle::Exception::Invalid account when the list - * of scopes in \p account is empty. - * - * @param account An account to be authenticated. - */ - void authenticate(KGoogle::Account::Ptr &account); - - /** - * The passed username will be injected in the OAuth form - * - * @param QString The username to use - */ - void setUsername(const QString &username); - - /** - * The passed password will be injected in the OAuth form - * - * @param QString The password to use - */ - void setPassword(const QString &password); - - /** - * Remove any previously set username or password - */ - void clearCredentials(); - - Q_SIGNALS: - /** - * This signal is emitted when access token and refresh token were successfully retrieved. - * - * When running the dialog synchronously via KDialog::exec() the dialog - * also emits KDialog::accepted() - * - * @param account Successfully authenticated account with name tokens set - */ - void authenticated(KGoogle::Account::Ptr &account); - - /** - * Emitted whenever an error occurs during the authentication. - */ - void error(const KGoogle::Error errCode, const QString &msg); - - private Q_SLOTS: - /** - * Emits error() signal with same parameters and displays the error - * on the dialog. - */ - void emitError(const KGoogle::Error errCode, const QString &msg); - - void webviewUrlChanged(const QUrl &url); - void webviewFinished(); - - void networkRequestFinished(QNetworkReply *reply); - void accountInfoReceived(KGoogle::Reply *reply); - - private: - /* GUI */ - QWidget *m_widget; - QProgressBar *m_progressbar; - QHBoxLayout *m_hbox; - QVBoxLayout *m_vbox; - QWebView *m_webiew; - QLabel *m_label; - - QString m_username; - QString m_password; - KGoogle::Account::Ptr m_account; -}; - -#endif // AUTHDIALOG_H diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/auth.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/auth.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/auth.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/auth.h 2012-06-16 02:20:58.000000000 +0000 @@ -30,6 +30,8 @@ #include #include +#include + namespace KWallet { class Wallet; @@ -41,6 +43,7 @@ { class AuthPrivate; +class AuthWidget; /** * Auth provides API for authentication against Google services. @@ -82,7 +85,7 @@ * * When there is no folder set libKGoogle will use default "libkgoogle" * folder. There is no problem storing tokens in the "libkgoogle" folder but - * remember that then the tokens will be shared accross all applications that + * remember that the tokens will then be shared across all applications that * won't set the folder either. It is strongly recommended for each application * to use it's own folder. * @@ -184,6 +187,32 @@ void authenticate(KGoogle::Account::Ptr &account, bool autoSave = true); /** + * @see authenticate() + * @since 0.3.2 + * + * Behaves exactly like Auth::authneticate(), but instead of displaying + * a dialog for full authentication, the method returns a AuthWidget, + * which can be simply embedded into an another application. + * + * If there is no need to display a widget (like only refreshing + * authentication tokens), the method will return null and continue + * like authenticate(). + * + * To start the actual process of authentication, user must call + * Kgoogle::AuthWidget::authneticate(). + * + * It's up to user to hide and destroy the widget when the authentication + * is finished (authneticated() or error() is emitted). + * + * @param account Account whose token is to be refreshed. + * @param autoSave Whether KGoogle::Auth should automatically + * call KGoogle::Auth::storeAccount() to save changes + * to KWallet. + * @return Returns a KGoogle::AuthWidget or null if there is no need for user interaction. + */ + KGoogle::AuthWidget* authenticateWithWidget(KGoogle::Account::Ptr &account, bool autoSave = true); + + /** * Revokes tokens for \p account and removes it from KWallet. * * This method will not throw any exception when the account @@ -192,7 +221,7 @@ * or connection fails (for any reason). * * @param account Account to which revoke access. - * @return Returns \p true when account is succesfully removed, \p false + * @return Returns \p true when account is successfully removed, \p false * when account does not exist or something fails. */ bool revoke(KGoogle::Account::Ptr &account); @@ -223,22 +252,26 @@ * called so if you want to change or remove it call \sa setPassword again * with empty string or \sa clearCredentials. * - * @param QString username to use + * @param QString password to use */ void setPassword(const QString &password); /** - * Set wether to auto close the authentication dialog on success or error + * Set whether to auto close the authentication dialog on success or error * * When \sa authenticate is called a dialog will appear to authenticate against * Google auth system, if set to true the dialog will be autoclosed in either * on success or on error. * - * By default the value is false. + * By default the value is true. + * + * As of 0.3.2 this method is deprecated and will be removed in 0.4 release. + * If you want to prevent the dialog from closing, use your own + * KDialog and use authenticateWithWidget() method to obtain an AuthWidget. * - * @param bool Wether auto close or not the dialog + * @param bool Whether auto close or not the dialog */ - void setDialogAutoClose(bool close); + void KDE_DEPRECATED setDialogAutoClose(bool close); /** * Sets to empty username and password @@ -258,9 +291,9 @@ void error(KGoogle::Error errCode, QString msg); /** - * Account was succesfully (re-)authenticated. + * Account was successfully (re-)authenticated. * - * This signal is emitted when \p account was succesfully authenticated + * This signal is emitted when \p account was successfully authenticated * (for the first time), or when just tokens were refreshed. */ void authenticated(KGoogle::Account::Ptr &account); diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/auth_p.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/auth_p.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/auth_p.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/auth_p.cpp 2012-06-16 02:20:58.000000000 +0000 @@ -30,7 +30,8 @@ #include #include "auth.h" -#include "authdialog.h" +#include "ui/authwidget.h" +#include "services/accountinfo.h" using namespace KGoogle; using namespace KWallet; @@ -39,7 +40,7 @@ QObject(), kwalletFolder("libkgoogle"), kwallet(0), - dialogAutoClose(false), + dialogAutoClose(true), q_ptr(parent) { } @@ -89,32 +90,51 @@ return Account::Ptr(new Account(account, map["accessToken"], map["refreshToken"], scopeUrls)); } +KGoogle::AuthWidget* AuthPrivate::authenticate(Account::Ptr& account, bool autoSave) +{ + if (!initKWallet()) { + return 0; + } + + if (account.isNull()) { + throw Exception::InvalidAccount(); + return 0; + } + if (account->refreshToken().isEmpty() || (account->m_scopesChanged == true)) { -void AuthPrivate::fullAuthentication(KGoogle::Account::Ptr &account, bool autoSave) + account->addScope(Services::AccountInfo::EmailScopeUrl); + return fullAuthentication(account, autoSave); + + } else { + + if (account->accountName().isEmpty()) { + throw Exception::InvalidAccount(); + return 0; + } + + refreshTokens(account, autoSave); + return 0; + } +} + +KGoogle::AuthWidget* AuthPrivate::fullAuthentication(KGoogle::Account::Ptr &account, bool autoSave) { Q_Q(Auth); - AuthDialog *dlg = new AuthDialog(KWindowSystem::activeWindow()); - dlg->setProperty("autoSaveAccount", QVariant(autoSave)); + AuthWidget *widget = new AuthWidget(); + widget->setProperty("autoSaveAccount", QVariant(autoSave)); + + connect(widget, SIGNAL(error(KGoogle::Error,QString)), + q, SIGNAL(error(KGoogle::Error,QString))); + connect(widget, SIGNAL(authenticated(KGoogle::Account::Ptr)), + this, SLOT(fullAuthenticationFinished(KGoogle::Account::Ptr))); + + widget->setUsername(username); + widget->setPassword(password); + widget->setAccount(account); - connect(dlg, SIGNAL(error(KGoogle::Error, QString)), - q, SIGNAL(error(KGoogle::Error, QString))); - connect(dlg, SIGNAL(authenticated(KGoogle::Account::Ptr&)), - this, SLOT(fullAuthenticationFinished(KGoogle::Account::Ptr&))); - connect(dlg, SIGNAL(accepted()), - dlg, SLOT(deleteLater())); - connect(dlg, SIGNAL(cancelClicked()), - SLOT(authDialogCancelled())); - - if (dialogAutoClose) { - connect(dlg, SIGNAL(error(KGoogle::Error,QString)), dlg, SLOT(close())); - } - - dlg->setUsername(username); - dlg->setPassword(password); - dlg->show(); - dlg->authenticate(account); + return widget; } void AuthPrivate::fullAuthenticationFinished(KGoogle::Account::Ptr &account) @@ -125,7 +145,7 @@ /* Actually this slot shouldn't be invoked by anything else but * AuthDialog, but just to make sure... */ - if (sender() && qobject_cast< AuthDialog* >(sender())) { + if (sender() && qobject_cast< AuthWidget* >(sender())) { autoSave = sender()->property("autoSaveAccount").toBool(); } @@ -238,10 +258,11 @@ * * We can't copy the new account over the old because that would not update * the value in all other copies of the cachedAcc object. */ - Q_FOREACH (const QString &accName, accountsCache.keys()) { + QMap< QString, Account::Ptr >::const_iterator iter = accountsCache.begin(); + while (iter != accountsCache.end()) { - Account::Ptr walletAcc = getAccountFromWallet(accName); - Account::Ptr cachedAcc = accountsCache.value(accName); + Account::Ptr walletAcc = getAccountFromWallet(iter.key()); + Account::Ptr cachedAcc = iter.value(); if (walletAcc->accessToken() != cachedAcc->accessToken()) { cachedAcc->setAccessToken(walletAcc->accessToken()); @@ -255,6 +276,8 @@ cachedAcc->setScopes(walletAcc->scopes()); cachedAcc->m_scopesChanged = false; } + + ++iter; } } diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/auth_p.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/auth_p.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/auth_p.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/auth_p.h 2012-06-16 02:20:58.000000000 +0000 @@ -16,8 +16,8 @@ along with this program. If not, see . */ -#ifndef LIBKGOOGLE_AUTH_P_H_ -#define LIBKGOOGLE_AUTH_P_H_ +#ifndef LIBKGOOGLE_AUTH_P_H +#define LIBKGOOGLE_AUTH_P_H #include #include @@ -35,6 +35,7 @@ { class Auth; +class AuthWidget; /** * \internal @@ -67,20 +68,22 @@ Account::Ptr getAccountFromWallet(const QString &account); public Q_SLOTS: - void fullAuthentication(KGoogle::Account::Ptr &account, bool autoSave); - void fullAuthenticationFinished(KGoogle::Account::Ptr &account); - void authDialogCancelled(); - + KGoogle::AuthWidget* authenticate(KGoogle::Account::Ptr &account, bool autoSave); void refreshTokens(KGoogle::Account::Ptr &account, bool autoSave); - void refreshTokensFinished(QNetworkReply *reply); + private Q_SLOTS: + void authDialogCancelled(); + void refreshTokensFinished(QNetworkReply *reply); void kwalletFolderChanged(const QString &folder); + void fullAuthenticationFinished(KGoogle::Account::Ptr &account); private: + KGoogle::AuthWidget* fullAuthentication(KGoogle::Account::Ptr &account, bool autoSave); + Auth* const q_ptr; Q_DECLARE_PUBLIC(Auth) }; } -#endif /* LIBKGOOGLE_AUTH_P_H_ */ \ No newline at end of file +#endif /* LIBKGOOGLE_AUTH_P_H */ diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/cmake/CMakeLists.txt akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/cmake/CMakeLists.txt --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/cmake/CMakeLists.txt 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/cmake/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ - -add_subdirectory(modules) \ No newline at end of file diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/cmake/modules/CMakeLists.txt akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/cmake/modules/CMakeLists.txt --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/cmake/modules/CMakeLists.txt 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/cmake/modules/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -set(module_install_dir ${DATA_INSTALL_DIR}/cmake/modules ) - -install(FILES FindLibKGoogle.cmake - DESTINATION ${module_install_dir} ) - - diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/cmake/modules/FindLibKGoogle.cmake akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/cmake/modules/FindLibKGoogle.cmake --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/cmake/modules/FindLibKGoogle.cmake 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/cmake/modules/FindLibKGoogle.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ -# - Try to find the LibKGoogle library -# Once done this will define -# -# LIBKGOOGLE_FOUND - System has LibKGoogle -# LIBKGOOGLE_INCLUDE_DIR - The LibKGoogle include directory -# LIBKGOOGLE_LIBRARY - The library needed to use LibKGoogle -# LIBKGOOGLE_DEFINITIONS - Compiler switches required for using LibKGoogle -# -# Copyright (c) 2011 Dan Vratil -# - - -IF (LIBKGOOGLE_INCLUDE_DIR AND LIBKGOOGLE_LIBRARY) - SET(LibKGoogle_FIND_QUIETLY TRUE) -ENDIF (LIBKGOOGLE_INCLUDE_DIR AND LIBKGOOGLE_LIBRARY) - -IF (NOT WIN32) - FIND_PACKAGE(PkgConfig) - PKG_CHECK_MODULES(PC_LIBKGOOGLE QUIET libkgoogle) - SET(LIBKGOOGLE_DEFINITIONS ${PC_LIBKGOOGLE_CFLAGS_OTHER}) -ENDIF (NOT WIN32) - -FIND_PATH(LIBKGOOGLE_INCLUDE_DIR libkgoogle/accessmanager.h - HINTS - ${PC_LIBKGOOGLE_INCLUDEDIR} - ${PC_LIBKGOOGLE_INCLUDE_DIRS} - PATH_SUFFIXES libkgoogle - ) - -FIND_LIBRARY(LIBKGOOGLE_LIBRARY NAMES kgoogle libkgoogle - HINTS - ${PC_LIBKGOOGLE_LIBDIR} - ${PC_LIBKGOOGLE_LIBRARY_DIRS} - ) - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibKGoogle DEFAULT_MSG LIBKGOOGLE_LIBRARY LIBKGOOGLE_INCLUDE_DIR) - -MARK_AS_ADVANCED(LIBKGOOGLE_INCLUDE_DIR LIBKGOOGLE_LIBRARY) - diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/CMakeLists.txt akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/CMakeLists.txt --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/CMakeLists.txt 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/CMakeLists.txt 2012-06-16 02:20:58.000000000 +0000 @@ -1,30 +1,9 @@ -project(libkgoogle) -set(KGOOGLE_VERSION_MAJOR 0) -set(KGOOGLE_VERSION_MINOR 3) -set(KGOOGLE_VERSION_RELEASE 1) -set(KGOOGLE_VERSION 0.3.1) - -cmake_minimum_required(VERSION 2.8) - -option(DEBUG_RAWDATA "Log raw data send and received from Google service (enables CMAKE_BUILD_TYPE=Debug)" FALSE) -if (DEBUG_RAWDATA) - SET(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE) - add_definitions(-DDEBUG_RAWDATA) -else (DEBUG_RAWDATA) - SET(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel.") -endif (DEBUG_RAWDATA) - -add_definitions(-DLIBKGOOGLE_LIBRARY) - -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${KDE4_ENABLE_EXCEPTIONS}" ) - set(libkgoogle_SRCS accessmanager.cpp accessmanager_p.cpp account.cpp auth.cpp auth_p.cpp - authdialog.cpp fetchlistjob.cpp object.cpp request.cpp @@ -41,6 +20,8 @@ services/contacts.cpp services/tasks.cpp ui/accountscombo.cpp + ui/authwidget.cpp + ui/authwidget_p.cpp ) set(libkgoogle_HDRS @@ -71,9 +52,8 @@ objects/tasklist.h) set(ui_HDRS - ui/accountscombo.h) - -add_subdirectory(cmake) + ui/accountscombo.h + ui/authwidget.h) kde4_add_library(kgoogle SHARED ${libkgoogle_SRCS}) @@ -85,7 +65,6 @@ ${KDE4_KDEUI_LIBS} ${KDEPIMLIBS_KABC_LIBS} ${KDEPIMLIBS_KMIME_LIBS} - ${qjson_LIBRARIES} # for Debian ${QJSON_LIBRARIES} ${QT_QTCORE_LIBRARY} ${QT_QTWEBKIT_LIBRARY} @@ -99,9 +78,9 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/libkgoogle.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig ) endif(NOT WIN32) - -install(TARGETS kgoogle ${INSTALL_TARGETS_DEFAULT_ARGS}) +install(TARGETS kgoogle EXPORT kgoogleLibraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS}) install(FILES ${libkgoogle_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/libkgoogle) install(FILES ${services_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/libkgoogle/services) install(FILES ${objects_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/libkgoogle/objects) install(FILES ${ui_HDRS} DESTINATION ${INCLUDE_INSTALL_DIR}/libkgoogle/ui) + diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/common.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/common.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/common.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/common.h 2012-06-16 02:20:58.000000000 +0000 @@ -47,18 +47,18 @@ AuthCancelled = 9, /// libKGoogle error - when authentication dialog is canceled /* Following error codes identify Google errors */ - OK = 200, /// Request succesfully executed. - Created = 201, /// Create request successfuly executed. - NoContent = 204, /// Tasks API returns 204 when task is sucessfully removed. + OK = 200, /// Request successfully executed. + Created = 201, /// Create request successfully executed. + NoContent = 204, /// Tasks API returns 204 when task is successfully removed. TemporarilyMoved = 302, /// The object is located on a different URL provided in reply. - NotModified = 304, /// Request was successfull, but no data were updated. + NotModified = 304, /// Request was successful, but no data were updated. BadRequest = 400, /// Invalid (malformed) request. Unauthorized = 401, /// Invalid or expired token. See KGoogleAccount::refreshTokens(). Forbidden = 403, /// The requested data are not accessible to this account NotFound = 404, /// Requested object was not found on the remote side Conflict = 409, /// Object on the remote site differs from the submitted one. See KGoogle::Object::setEtag(). Gone = 410, /// The requested does not exist anymore on the remote site - InternalError = 500, /// An unexpected error on the Google service occuerd + InternalError = 500, /// An unexpected error on the Google service occurred QuotaExceeded = 503 /// User quota has been exceeded, the request should be send again later. }; @@ -181,7 +181,7 @@ } /* namespace Exception */ /** - * Struct to store additional informations about a feed. + * Struct to store additional information about a feed. */ class FeedData { diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/fetchlistjob.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/fetchlistjob.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/fetchlistjob.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/fetchlistjob.h 2012-06-16 02:20:58.000000000 +0000 @@ -20,7 +20,7 @@ #ifndef LIBKGOOGLE_FETCHLISTJOB_H #define LIBKGOOGLE_FETCHLISTJOB_H -#include +#include #include diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/libkgoogle_export.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/libkgoogle_export.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/libkgoogle_export.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/libkgoogle_export.h 2012-06-16 02:20:58.000000000 +0000 @@ -1,7 +1,32 @@ +/* + LibKGoogle + Copyright (C) 2012 Dan Vratil + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + + +#ifndef LIBKGOOGLE_EXPORT_H +#define LIBKGOOGLE_EXPORT_H + #include #if defined(LIBKGOOGLE_LIBRARY) # define LIBKGOOGLE_EXPORT Q_DECL_EXPORT #else # define LIBKGOOGLE_EXPORT Q_DECL_IMPORT -#endif \ No newline at end of file +#endif + +#endif diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/accountinfo.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/accountinfo.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/accountinfo.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/accountinfo.h 2012-06-16 02:20:58.000000000 +0000 @@ -35,15 +35,15 @@ class AccountInfoData; /** - * AccountInfo contains informations about user's Google account. + * AccountInfo contains information about user's Google account. * - * It is possible to obtain only informations about account to which + * It is possible to obtain only information about account to which * we have access token. * - * Some informations might be empty, but id and email are guaranteed to + * Some information might be empty, but id and email are guaranteed to * be always filled. * - * The accountInfo service provides read-only acces. + * The accountInfo service provides read-only access. */ class LIBKGOOGLE_EXPORT AccountInfo : public KGoogle::Object { diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/accountinfo_p.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/accountinfo_p.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/accountinfo_p.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/accountinfo_p.h 2012-06-16 02:20:58.000000000 +0000 @@ -58,4 +58,4 @@ } /* namespace KGoogle */ -#endif // LIBKGOOGLE_OBJECTS_ACCOUNTINFO_P_H \ No newline at end of file +#endif // LIBKGOOGLE_OBJECTS_ACCOUNTINFO_P_H diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/calendar.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/calendar.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/calendar.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/calendar.h 2012-06-16 02:20:58.000000000 +0000 @@ -27,13 +27,13 @@ #include #ifdef WITH_KCAL -#include -#include +#include +#include typedef KCal::Alarm* AlarmPtr; using namespace KCal; #else -#include -#include +#include +#include typedef KCalCore::Alarm::Ptr AlarmPtr; using namespace KCalCore; #endif @@ -55,11 +55,11 @@ typedef QSharedPointer< Reminder > Ptr; typedef QList< Ptr > List; - Reminder(); - Reminder(const Alarm::Type &type, const Duration &startOffset = Duration(0)); + explicit Reminder(const Alarm::Type &type, const Duration &startOffset = Duration(0)); Reminder(const Reminder &other); + Reminder(); - ~Reminder(); + virtual ~Reminder(); Alarm::Type type() const; @@ -87,11 +87,11 @@ typedef QSharedPointer Ptr; typedef QList List; - Calendar(); + explicit Calendar(); Calendar(const Calendar &other); - ~Calendar(); + virtual ~Calendar(); /** * Sets UID of the calendar. @@ -144,7 +144,7 @@ void setTimezone(const QString &timezone); /** - * Returns wheter calendar is editable or read-only. + * Returns whether calendar is editable or read-only. */ bool editable() const; diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/calendar_p.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/calendar_p.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/calendar_p.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/calendar_p.h 2012-06-16 02:20:58.000000000 +0000 @@ -16,14 +16,17 @@ along with this program. If not, see . */ +#ifndef LIBKGOOGLE_OBJECTS_CALENDAR_P_H +#define LIBKGOOGLE_OBJECTS_CALENDAR_P_H + #include #include #ifdef WITH_KCAL -#include +#include using namespace KCal; #else -#include +#include using namespace KCalCore; #endif @@ -64,3 +67,5 @@ } // namespace Objects } // namespace KGoogle + +#endif /* LIBKGOOGLE_OBJECTS_CALENDAR_P_H */ diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/contact.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/contact.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/contact.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/contact.cpp 2012-06-16 02:20:58.000000000 +0000 @@ -16,15 +16,15 @@ along with this program. If not, see . */ -#include "object.h" #include "contact.h" #include "contact_p.h" +#include "object.h" #include "services/contacts.h" #include -#include -#include +#include +#include using namespace KGoogle::Objects; @@ -50,8 +50,8 @@ KABC::Addressee(other), d(other.d) { - QStringList groups = custom("GCALENDAR", "groupMembershipInfo").split(",", QString::SkipEmptyParts); - Q_FOREACH(QString group, groups) { + QStringList groups = custom("GCALENDAR", "groupMembershipInfo").split(',', QString::SkipEmptyParts); + Q_FOREACH(const QString &group, groups) { d->groups.insert(group, false); } } @@ -60,8 +60,8 @@ Addressee(other), d(new ContactData) { - QStringList groups = custom("GCALENDAR", "groupMembershipInfo").split(",", QString::SkipEmptyParts); - Q_FOREACH(QString group, groups) { + QStringList groups = custom("GCALENDAR", "groupMembershipInfo").split(',', QString::SkipEmptyParts); + Q_FOREACH(const QString &group, groups) { d->groups.insert(group, false); } } @@ -81,7 +81,7 @@ void Contact::setPhotoUrl(const QString& photoUrl) { - d->photoUrl = QUrl(photoUrl); + d->photoUrl = KUrl(photoUrl); } void Contact::setPhotoUrl(const QUrl& photoUrl) @@ -191,7 +191,7 @@ d->groups.insert(group, false); - QStringList groups = custom("GCALENDAR", "groupMembershipInfo").split(",", QString::SkipEmptyParts); + QStringList groups = custom("GCALENDAR", "groupMembershipInfo").split(',', QString::SkipEmptyParts); if (!groups.contains(group)) { groups.append(group); } @@ -204,20 +204,20 @@ insertCustom("GCALENDAR", "groupMembershipInfo", groups.join(",")); d->groups.clear(); - Q_FOREACH(QString group, groups) { + Q_FOREACH(const QString &group, groups) { d->groups.insert(group, false); } } QStringList Contact::groups() const { - return custom("GCALENDAR", "groupMembershipInfo").split(",", QString::SkipEmptyParts); + return custom("GCALENDAR", "groupMembershipInfo").split(',', QString::SkipEmptyParts); } void Contact::clearGroups() { QStringList groups = d->groups.keys(); - Q_FOREACH(QString group, groups) { + Q_FOREACH(const QString &group, groups) { d->groups.insert(group, true); } } diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/contact.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/contact.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/contact.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/contact.h 2012-06-16 02:20:58.000000000 +0000 @@ -23,8 +23,8 @@ #include #include -#include -#include +#include +#include #include #include @@ -65,7 +65,7 @@ void setDeleted(const bool deleted); /** - * Returns wheter contact was deleted on the remote server. + * Returns whether contact was deleted on the remote server. */ bool deleted() const; diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/contact_p.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/contact_p.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/contact_p.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/contact_p.h 2012-06-16 02:20:58.000000000 +0000 @@ -24,7 +24,7 @@ #include #include -#include +#include namespace KGoogle { diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/contactsgroup_p.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/contactsgroup_p.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/contactsgroup_p.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/contactsgroup_p.h 2012-06-16 02:20:58.000000000 +0000 @@ -1,20 +1,23 @@ /* - * libKGoogle - Objects - ContactsGroup - * Copyright (C) 2012 Dan Vratil - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ + libKGoogle - Objects - ContactsGroup + Copyright (C) 2012 Dan Vratil + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef LIBKGOOGLE_OBJECTS_CONTACTSGROUP_P_H +#define LIBKGOOGLE_OBJECTS_CONTACTSGROUP_P_H #include #include @@ -47,3 +50,5 @@ } /* namespace Objects */ } /* namespace KGoogle */ + +#endif /* LIBKGOOGLE_OBJECTS_CONTACTSGROUP_P_H */ diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/event.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/event.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/event.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/event.h 2012-06-16 02:20:58.000000000 +0000 @@ -28,20 +28,20 @@ #include #ifdef WITH_KCAL -#include -#include -#include -#include +#include +#include +#include +#include #include typedef boost::shared_ptr EventPtr; typedef KCal::Attendee* AttendeePtr; typedef KCal::Person* PersonPtr; typedef KCal::Alarm* AlarmPtr; #else -#include -#include -#include -#include +#include +#include +#include +#include typedef KCalCore::Event::Ptr EventPtr; typedef KCalCore::Attendee::Ptr AttendeePtr; typedef KCalCore::Person::Ptr PersonPtr; @@ -89,7 +89,7 @@ void setDeleted(const bool deleted); /** - * Returns wheter the event was removed on the remote server. + * Returns whether the event was removed on the remote server. */ bool deleted() const; diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/event_p.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/event_p.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/event_p.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/event_p.h 2012-06-16 02:20:58.000000000 +0000 @@ -16,8 +16,8 @@ along with this program. If not, see . */ -#ifndef EVENT_P_H_ -#define EVENT_P_H_ +#ifndef LIBKGOOGLE_OBJECTS_EVENT_P_H +#define LIBKGOOGLE_OBJECTS_EVENT_P_H #include @@ -43,4 +43,4 @@ } // namespace KGoogle -#endif /* EVENT_P_H_ */ +#endif /* LIBKGOOGLE_OBJECTS_EVENT_P_H */ diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/task.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/task.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/objects/task.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/objects/task.h 2012-06-16 02:20:58.000000000 +0000 @@ -27,11 +27,11 @@ #include #ifdef WITH_KCAL -#include +#include #include typedef boost::shared_ptr TodoPtr; #else -#include +#include typedef KCalCore::Todo::Ptr TodoPtr; #endif diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/reply.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/reply.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/reply.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/reply.cpp 2012-06-16 02:20:58.000000000 +0000 @@ -22,7 +22,7 @@ #include #include -#include +#include namespace KGoogle { diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/request.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/request.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/request.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/request.cpp 2012-06-16 02:20:58.000000000 +0000 @@ -17,8 +17,8 @@ */ -#include "account.h" #include "request.h" +#include "account.h" #include #include diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/request.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/request.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/request.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/request.h 2012-06-16 02:20:58.000000000 +0000 @@ -128,7 +128,7 @@ * Set a value of an objects property. * * This mimics functionality of QObject::setProperty(). It - * allows user to store additional informations as object's + * allows user to store additional information as object's * properties. * * @param name Name of a property. @@ -142,7 +142,7 @@ QVariant property(const QString &name) const; /** - * Returns wheter request has a property \p name. + * Returns whether request has a property \p name. */ bool hasProperty(const QString &name) const; diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/service.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/service.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/service.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/service.h 2012-06-16 02:20:58.000000000 +0000 @@ -36,7 +36,7 @@ /** * A base class for all services. * - * Service is a class that provides additional informations + * Service is a class that provides additional information * about a Google service and implements parsers for objects * from service. */ diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/services/accountinfo.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/services/accountinfo.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/services/accountinfo.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/services/accountinfo.h 2012-06-16 02:20:58.000000000 +0000 @@ -67,7 +67,7 @@ static QUrl fetchUrl(); /** - * The AccountInfo always returns informations about single account, never feed. + * The AccountInfo always returns information about single account, never feed. * * This method does nothing. */ diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/services/calendar.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/services/calendar.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/services/calendar.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/services/calendar.cpp 2012-06-16 02:20:58.000000000 +0000 @@ -23,25 +23,26 @@ #include "objects/event.h" #ifdef WITH_KCAL -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include using namespace KCal; #else -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include using namespace KCalCore; #endif #include #include -#include +#include +#include #include @@ -180,16 +181,18 @@ QUrl Services::Calendar::fetchCalendarUrl(const QString& calendarID) { - QByteArray ba("https://www.googleapis.com/calendar/v3/users/me/calendarList/"); - ba.append(QUrl::toPercentEncoding(calendarID)); - return QUrl::fromEncoded(ba); + KUrl url("https://www.googleapis.com/calendar/v3/users/me/calendarList/"); + url.addPath(calendarID); + + return url; } QUrl Services::Calendar::updateCalendarUrl(const QString &calendarID) { - QByteArray ba("https://www.googleapis.com/calendar/v3/calendars/"); - ba.append(QUrl::toPercentEncoding(calendarID)); - return QUrl::fromEncoded(ba); + KUrl url("https://www.googleapis.com/calendar/v3/calendars/"); + url.addPath(calendarID); + + return url; } QUrl Services::Calendar::createCalendarUrl() @@ -199,56 +202,70 @@ QUrl Services::Calendar::removeCalendarUrl(const QString& calendarID) { - QByteArray ba("https://www.googleapis.com/calendar/v3/calendars/"); - ba.append(QUrl::toPercentEncoding(calendarID)); - return QUrl::fromEncoded(ba); + KUrl url("https://www.googleapis.com/calendar/v3/calendars/"); + url.addPath(calendarID); + + return url; } QUrl Services::Calendar::fetchEventsUrl(const QString& calendarID) { - QByteArray ba("https://www.googleapis.com/calendar/v3/calendars/"); - ba.append(QUrl::toPercentEncoding(calendarID)); - ba.append("/events?maxResults=20"); - return QUrl::fromEncoded(ba); + KUrl url("https://www.googleapis.com/calendar/v3/calendars/"); + url.addPath(calendarID); + url.addPath("events"); + url.addQueryItem("maxResults", "20"); + + return url; } QUrl Services::Calendar::fetchEventUrl(const QString& calendarID, const QString& eventID) { - QByteArray ba("https://www.googleapis.com/calendar/v3/calendars/"); - ba.append(QUrl::toPercentEncoding(calendarID)).append("/events/").append(eventID.toLatin1()); - return QUrl::fromEncoded(ba); + KUrl url("https://www.googleapis.com/calendar/v3/calendars/"); + url.addPath(calendarID); + url.addPath("events"); + url.addPath(eventID); + + return url; } QUrl Services::Calendar::updateEventUrl(const QString& calendarID, const QString& eventID) { - QByteArray ba("https://www.googleapis.com/calendar/v3/calendars/"); - ba.append(QUrl::toPercentEncoding(calendarID)).append("/events/").append(eventID.toLatin1()); - return QUrl::fromEncoded(ba); + KUrl url("https://www.googleapis.com/calendar/v3/calendars/"); + url.addPath(calendarID); + url.addPath("events"); + url.addPath(eventID); + + return url; } QUrl Services::Calendar::createEventUrl(const QString& calendarID) { - QByteArray ba("https://www.googleapis.com/calendar/v3/calendars/"); - ba.append(QUrl::toPercentEncoding(calendarID)).append("/events"); - return QUrl::fromEncoded(ba); + KUrl url("https://www.googleapis.com/calendar/v3/calendars/"); + url.addPath(calendarID); + url.addPath("events"); + + return url; } QUrl Services::Calendar::removeEventUrl(const QString& calendarID, const QString& eventID) { - QByteArray ba("https://www.googleapis.com/calendar/v3/calendars/"); - ba.append(QUrl::toPercentEncoding(calendarID)).append("/events/").append(eventID.toLatin1()); - return QUrl::fromEncoded(ba); + KUrl url("https://www.googleapis.com/calendar/v3/calendars/"); + url.addPath(calendarID); + url.addPath("events"); + url.addPath(eventID); + + return url; } QUrl Services::Calendar::moveEventUrl(const QString& sourceCalendar, const QString& destCalendar, const QString& eventID) { - QByteArray ba("https://www.googleapis.com/calendar/v3/calendars/"); - ba.append(QUrl::toPercentEncoding(sourceCalendar)) - .append(QString("/events/").toLatin1()) - .append(eventID.toLatin1()) - .append(QString("?destination=").toLatin1()) - .append(destCalendar.toLatin1()); - return QUrl::fromEncoded(ba); + KUrl url("https://www.googleapis.com/calendar/v3/calendars/"); + url.addPath(sourceCalendar); + url.addPath("events"); + url.addPath(eventID); + url.addQueryItem("destination", destCalendar); + + return url; } @@ -336,7 +353,7 @@ { QList< KGoogle::Object* > output; - Q_FOREACH(QVariant i, feed) { + Q_FOREACH(const QVariant &i, feed) { output.append(CalendarPrivate::JSONToCalendar(i.toMap())); } @@ -513,21 +530,25 @@ /* Extended properties */ QVariantMap extendedProperties = event["extendedProperties"].toMap(); - QVariantMap privateProperties = extendedProperties["private"].toMap(); - Q_FOREACH(const QString & key, privateProperties.keys()) { - - if (key == "categories") { - object->setCategories(privateProperties.value(key).toString()); + QVariantMap privateProperties = extendedProperties["private"].toMap(); + QMap< QString, QVariant >::const_iterator iter = privateProperties.begin(); + while (iter != privateProperties.end()) { + if (iter.key() == "categories") { + object->setCategories(iter.value().toString()); } + + ++iter; } QVariantMap sharedProperties = extendedProperties["shared"].toMap(); - Q_FOREACH(const QString & key, sharedProperties.keys()) { - - if (key == "categories") { - object->setCategories(sharedProperties.value(key).toString()); + iter = sharedProperties.begin(); + while (iter != sharedProperties.end()) { + if (iter.key() == "categories") { + object->setCategories(iter.value().toString()); } + + ++iter; } return dynamic_cast< KGoogle::Object* >(object); @@ -724,7 +745,7 @@ { QList< KGoogle::Object* > output; - Q_FOREACH(QVariant i, feed) { + Q_FOREACH(const QVariant &i, feed) { output.append(JSONToEvent(i.toMap())); } @@ -737,26 +758,26 @@ QString value; KTimeZone tz; - QString left = rule.left(rule.indexOf(":")); - QStringList params = left.split(";"); + QString left = rule.left(rule.indexOf(':')); + QStringList params = left.split(';'); Q_FOREACH(const QString & param, params) { - if (param.startsWith("VALUE")) { - value = param.mid(param.indexOf("=") + 1); - } else if (param.startsWith("TZID")) { - QString tzname = param.mid(param.indexOf("=") + 1); + if (param.startsWith(QLatin1String("VALUE"))) { + value = param.mid(param.indexOf('=') + 1); + } else if (param.startsWith(QLatin1String("TZID"))) { + QString tzname = param.mid(param.indexOf('=') + 1); tz = KSystemTimeZones::zone(tzname); } } QString datesStr = rule.mid(rule.lastIndexOf(":") + 1); - QStringList dates = datesStr.split(","); - Q_FOREACH(QString date, dates) { + QStringList dates = datesStr.split(','); + Q_FOREACH(const QString &date, dates) { QDate dt; if (value == "DATE") { dt = QDate::fromString(date, "yyyyMMdd"); } else if (value == "PERIOD") { - QString start = date.left(date.indexOf("/")); + QString start = date.left(date.indexOf('/')); KDateTime kdt = AccessManager::RFC3339StringToDate(start); if (tz.isValid()) { kdt.setTimeSpec(tz); diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/services/calendar.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/services/calendar.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/services/calendar.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/services/calendar.h 2012-06-16 02:20:58.000000000 +0000 @@ -24,10 +24,10 @@ #include #ifdef WITH_KCAL -#include +#include using namespace KCal; #else -#include +#include using namespace KCalCore; #endif @@ -171,7 +171,7 @@ const QUrl& scopeUrl() const; /** - * Returns wheter service supports reading data in JSON format. + * Returns whether service supports reading data in JSON format. * * @param urlParam Returns value of "alt" query. Usually is * "json" or "jsonc". When service does not support reading JSON @@ -180,7 +180,7 @@ static bool supportsJSONRead(QString* urlParam); /** - * Returns wheter service supports writing data in JSON format. + * Returns whether service supports writing data in JSON format. * * @param urlParam Returns value of "alt" query. Usually is * "json" or "jsonc". When service does not support writing JSON diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/services/contacts.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/services/contacts.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/services/contacts.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/services/contacts.cpp 2012-06-16 02:20:58.000000000 +0000 @@ -88,13 +88,13 @@ QVariantMap feed = head["feed"].toMap(); - Q_FOREACH(QVariant c, feed["category"].toList()) { + Q_FOREACH(const QVariant &c, feed["category"].toList()) { QVariantMap category = c.toMap(); bool groups = (category["term"].toString() == "http://schemas.google.com/contact/2008#group"); QVariantList entries = feed["entry"].toList(); - Q_FOREACH(QVariant e, entries) { + Q_FOREACH(const QVariant &e, entries) { if (groups) output << ContactsPrivate::JSONToGroup(e.toMap()); else @@ -103,10 +103,10 @@ } QVariantList links = feed["link"].toList(); - Q_FOREACH(QVariant l, links) { + Q_FOREACH(const QVariant &l, links) { QVariantMap link = l.toMap(); if (link["rel"].toString() == "next") { - feedData.nextPageUrl = QUrl::fromEncoded(link["href"].toByteArray()); + feedData.nextPageUrl = KUrl(link["href"].toString()); break; } } @@ -132,7 +132,7 @@ entry = data["entry"].toMap(); - Q_FOREACH(QVariant c, entry["category"].toList()) { + Q_FOREACH(const QVariant &c, entry["category"].toList()) { QVariantMap category = c.toMap(); if (category["term"].toString() == "http://schemas.google.com/contact/2008#group") { @@ -427,7 +427,7 @@ /* Relationships */ if (data.contains("gContact$relation")) { - Q_FOREACH(QVariant r, data["gContact$relation"].toList()) { + Q_FOREACH(const QVariant &r, data["gContact$relation"].toList()) { QVariantMap relation = r.toMap(); if (relation["rel"].toString() == "spouse") { object->setSpousesName(relation["$t"].toString()); @@ -448,7 +448,7 @@ /* Anniversary */ if (data.contains("gContact$event")) { - Q_FOREACH(QVariant e, data["gContact$event"].toList()) { + Q_FOREACH(const QVariant &e, data["gContact$event"].toList()) { QVariantMap event = e.toMap(); if (event["rel"].toString() == "anniversary") { @@ -460,7 +460,7 @@ /* Websites */ if (data.contains("gContact$website")) { - Q_FOREACH(QVariant w, data["gContact$website"].toList()) { + Q_FOREACH(const QVariant &w, data["gContact$website"].toList()) { QVariantMap web = w.toMap(); if (web["rel"].toString() == "home-page") { @@ -647,14 +647,14 @@ } /* Emails */ - Q_FOREACH(QString email, contact->emails()) { + Q_FOREACH(const QString &email, contact->emails()) { output.append(""); } /* IMs */ QString im_str(""); - Q_FOREACH(QString im, contact->customs()) { - if (im.startsWith("messaging/")) { + Q_FOREACH(const QString &im, contact->customs()) { + if (im.startsWith(QLatin1String("messaging/"))) { QString key = im.left(im.indexOf(':')); QString value = im.mid(im.indexOf(':') + 1); QString proto = key.mid(10); @@ -668,12 +668,12 @@ /* Phone numbers */ QString phone_str("%2"); - Q_FOREACH(KABC::PhoneNumber number, contact->phoneNumbers()) { + Q_FOREACH(const KABC::PhoneNumber &number, contact->phoneNumbers()) { output.append(phone_str.arg(Objects::Contact::phoneTypeToScheme(number.type()), number.number()).toUtf8()); } /* Address */ - Q_FOREACH(KABC::Address address, contact->addresses()) { + Q_FOREACH(const KABC::Address &address, contact->addresses()) { output.append(""); @@ -699,7 +699,7 @@ output.append(""); } - QStringList groups = contact->custom("GCALENDAR", "groupMembershipInfo").split(","); + QStringList groups = contact->custom("GCALENDAR", "groupMembershipInfo").split(','); if ((groups.length() > 0) && !groups.at(0).isEmpty()) { Q_FOREACH(const QString & group, groups) { bool removed = contact->groupIsDeleted(group); @@ -712,7 +712,7 @@ /* User-defined fields */ QStringList customs = contact->customs(); QString defined_str(""); - Q_FOREACH(QString customStr, customs) { + Q_FOREACH(const QString &customStr, customs) { QString key = customStr.left(customStr.indexOf(':')); if (!parsedCustoms.contains(key)) { QString value = customStr.mid(customStr.indexOf(':') + 1); diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/services/contacts.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/services/contacts.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/services/contacts.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/services/contacts.h 2012-06-16 02:20:58.000000000 +0000 @@ -176,7 +176,7 @@ static QUrl photoUrl(const QString &user, const QString &contactId); /** - * Returns wheter service supports reading data in JSON format. + * Returns whether service supports reading data in JSON format. * * @param urlParam Returns a value of "alt" URL query. Usually is * "json" or "jsonc". When service does not support reading JSON @@ -185,7 +185,7 @@ static bool supportsJSONRead(QString* urlParam); /** - * Returns wheter service supports writing data in JSON format. + * Returns whether service supports writing data in JSON format. * * @param urlParam Returns a value of "alt" URL query. Usually is * "json" or "jsonc". When service does not support writing JSON diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/services/tasks.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/services/tasks.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/services/tasks.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/services/tasks.cpp 2012-06-16 02:20:58.000000000 +0000 @@ -215,7 +215,7 @@ bool Tasks::supportsJSONRead(QString* urlParam) { if (urlParam) - *urlParam = QString(); + urlParam->clear(); return true; } @@ -223,7 +223,7 @@ bool Tasks::supportsJSONWrite(QString* urlParam) { if (urlParam) - *urlParam = QString(); + urlParam->clear(); return true; } @@ -336,7 +336,7 @@ { QList< KGoogle::Object* > list; - Q_FOREACH(QVariant item, items) { + Q_FOREACH(const QVariant &item, items) { list.append(JSONToTaskList(item.toMap())); } @@ -347,7 +347,7 @@ { QList< KGoogle::Object* > list; - Q_FOREACH(QVariant item, items) { + Q_FOREACH(const QVariant &item, items) { list.append(JSONToTask(item.toMap())); } diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/services/tasks.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/services/tasks.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/services/tasks.h 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/services/tasks.h 2012-06-16 02:20:58.000000000 +0000 @@ -157,7 +157,7 @@ static QUrl removeTaskListUrl(const QString &tasklistID); /** - * Returns wheter service supports reading data in JSON format. + * Returns whether service supports reading data in JSON format. * * @param urlParam Returns empty string, because Tasks API supports * only JSON, so there's no need for explicit parameter for it. @@ -165,7 +165,7 @@ static bool supportsJSONRead(QString* urlParam); /** - * Returns wheter service supports writing data in JSON format. + * Returns whether service supports writing data in JSON format. * * @param urlParam Returns empty string, because Tasks API supports * only JSON, so there's no need for explicit parameter for it. diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/ui/authwidget.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/ui/authwidget.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/ui/authwidget.cpp 1970-01-01 00:00:00.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/ui/authwidget.cpp 2012-06-16 02:20:58.000000000 +0000 @@ -0,0 +1,119 @@ +/* + LibKGoogle - AuthWidget + Copyright (C) 2012 Dan Vratil + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#include "authwidget.h" +#include "authwidget_p.h" +#include "auth.h" + +#include + + +using namespace KGoogle; + +AuthWidget::AuthWidget(QWidget* parent): + QWidget(parent), + d_ptr(new AuthWidgetPrivate(this)) +{ + +} + +AuthWidget::~AuthWidget() +{ + +} + +void AuthWidget::setUsername(const QString& username) +{ + Q_D(AuthWidget); + d->username = username; +} + +void AuthWidget::setPassword(const QString& password) +{ + Q_D(AuthWidget); + d->password = password; +} + +void AuthWidget::clearCredentials() +{ + Q_D(AuthWidget); + d->username.clear(); + d->password.clear(); +} + +void AuthWidget::setAccount(Account::Ptr& account) +{ + Q_D(AuthWidget); + d->account = account; +} + +void AuthWidget::setShowProgressBar(bool showProgressBar) +{ + Q_D(AuthWidget); + d->showProgressBar = showProgressBar; + + if (showProgressBar && d->progress == UserLogin) { + d->progressbar->setVisible(true); + } else { + d->progressbar->setVisible(false); + } +} + +bool AuthWidget::getShowProgressBar() const +{ + return d_func()->showProgressBar; +} + +AuthWidget::Progress AuthWidget::getProgress() const +{ + return d_func()->progress; +} + +void AuthWidget::authenticate() +{ + Q_D(AuthWidget); + + if (d->account.isNull() || d->account->scopes().isEmpty()) { + throw KGoogle::Exception::InvalidAccount(); + return; + } + + QStringList scopes; + Q_FOREACH(const QUrl & scope, d->account->scopes()) { + scopes << scope.toString(); + } + + QUrl url("https://accounts.google.com/o/oauth2/auth"); + url.addQueryItem("client_id", KGoogle::Auth::instance()->apiKey()); + url.addQueryItem("redirect_uri", "urn:ietf:wg:oauth:2.0:oob"); + url.addQueryItem("scope", scopes.join(" ")); + url.addQueryItem("response_type", "code"); + +#ifdef DEBUG_RAWDATA + kDebug() << "Requesting new token:" << url; +#endif + + d->webview->setVisible(true); + if (d->showProgressBar) { + d->progressbar->setVisible(true); + } + + d->webview->setUrl(url); + d->setProgress(AuthWidget::UserLogin); +} diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/ui/authwidget.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/ui/authwidget.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/ui/authwidget.h 1970-01-01 00:00:00.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/ui/authwidget.h 2012-06-16 02:20:58.000000000 +0000 @@ -0,0 +1,165 @@ +/* + LibKGoogle - AuthWidget + Copyright (C) 2012 Dan Vratil + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#ifndef KGOOGLE_AUTHWIDGET_H +#define KGOOGLE_AUTHWIDGET_H + +#include +#include +#include + +#include + +namespace KGoogle { + +class AuthWidgetPrivate; + +/** + * A widget for authentication that can be easilly embedded + * to any application. + * + * @since 0.3.2 + */ +class LIBKGOOGLE_EXPORT AuthWidget : public QWidget +{ + Q_OBJECT + Q_PROPERTY(bool showProgressBar WRITE setShowProgressBar READ getShowProgressBar); + public: + /** + * Describes progress of the authentication so that external observers can react + * (for example you can hide the widget after user login) + */ + enum Progress { + None, /**< Initial state, before authenticate() is called */ + UserLogin, /**< The webview where user has to login to Google is displayed */ + TokensRetrieval, /**< Tokens are being retrieved (webview no longer visible) */ + Finished, /**< Tokens were retrieved and authenticated() signal has been emitted */ + Error /**< An error occurred and error() signal has been emitted */ + }; + + explicit AuthWidget(QWidget* parent = 0); + + virtual ~AuthWidget(); + + /** + * Runs the authentication. + * + * Displays the webview and starts the actual process of authentication. + * + * The method will throw an KGoogle::InvalidAccount exception if + * no account was set via setAccount() before invoking this method. + */ + void authenticate(); + + /** + * Sets the username that will be used when authenticate is called + * + * The username will be automatically filled in the Google login + * form in the authentication widget. + * + * Be aware that the username will be set every time \sa authenticate is + * called so if you want to change or remove it call \sa setUsername again + * with empty string or \sa clearCredentials. + * + * @param QString username to use + */ + void setUsername(const QString &username); + + /** + * Sets the password that will be used when authenticate is called + * + * The password will be automatically filled in the Google login + * form in the authentication widget. + * + * Be aware that the password will be set every time \sa authenticate is + * called so if you want to change or remove it call \sa setPassword again + * with empty string or \sa clearCredentials. + * + * @param QString password to use + */ + void setPassword(const QString &password); + + /** + * Sets to empty username and password + * + * Sets to empty the username and the password which were set by + * calling \sa setUsername and \sa setPassword. + */ + void clearCredentials(); + + /** + * Sets an account for which to obtain authentication. + */ + void setAccount(KGoogle::Account::Ptr &account); + + /** + * Sets whether to show progressbar above the webview when loading + * and displaying the Google login form. + * + * Default is true + * + * @param showProgressBar + */ + void setShowProgressBar(bool showProgressBar); + + /** + * Returns whether a progressbar above webview will be shown. + * + * @see setShowProgressBar + */ + bool getShowProgressBar() const; + + /** + * Returns current progress state. + * + * @see progress() + */ + AuthWidget::Progress getProgress() const; + + Q_SIGNALS: + /** + * Account was successfully authenticated. + * + * This signal is emitted when the authentication was successful + * and tokens were stored within the \p account + */ + void authenticated(KGoogle::Account::Ptr &account); + + /** + * Emitted when an error occurs + * + * Signalizes any authentication error + */ + void error(const KGoogle::Error errCode, const QString &msg); + + /** + * Emitted whenever a state of the authentication process changes. + * + * @param progress The new state of authentication + */ + void progress(KGoogle::AuthWidget::Progress progress); + + private: + AuthWidgetPrivate *d_ptr; + Q_DECLARE_PRIVATE(AuthWidget); +}; + +} /* namespace KGoogle */ + +#endif // KGOOGLE_AUTHWIDGET_H diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/ui/authwidget_p.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/ui/authwidget_p.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/ui/authwidget_p.cpp 1970-01-01 00:00:00.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/ui/authwidget_p.cpp 2012-06-16 02:20:58.000000000 +0000 @@ -0,0 +1,245 @@ +/* + LibKGoogle - AuthWidgetPrivate + Copyright (C) 2012 Dan Vratil + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#include "authwidget_p.h" +#include "auth.h" +#include "accessmanager.h" +#include "request.h" +#include "reply.h" +#include "services/accountinfo.h" +#include "objects/accountinfo.h" + +#include +#include +#include +#include + +#include +#include + + +using namespace KGoogle; + +AuthWidgetPrivate::AuthWidgetPrivate(AuthWidget *parent): + QObject(), + showProgressBar(true), + progress(AuthWidget::None), + q_ptr(parent) +{ + qRegisterMetaType< KGoogle::Services::AccountInfo >("AccountInfo"); + + setupUi(); +} + +AuthWidgetPrivate::~AuthWidgetPrivate() +{ + delete vbox; + delete label; + delete progressbar; + delete webview; +} + + +void AuthWidgetPrivate::setupUi() +{ + Q_Q(AuthWidget); + + vbox = new QVBoxLayout(q); + q->setLayout(vbox); + + label = new QLabel(q); + label->setText("" + i18n("Authorizing token. This should take just a moment...") + ""); + label->setWordWrap(true); + label->setAlignment(Qt::AlignCenter); + label->setVisible(false); + vbox->addWidget(label); + + progressbar = new QProgressBar(q); + progressbar->setMinimum(0); + progressbar->setMaximum(100); + progressbar->setValue(0); + vbox->addWidget(progressbar); + + webview = new QWebView(q); + vbox->addWidget(webview); + connect(webview, SIGNAL(loadProgress(int)), progressbar, SLOT(setValue(int))); + connect(webview, SIGNAL(urlChanged(QUrl)), this, SLOT(webviewUrlChanged(QUrl))); + connect(webview, SIGNAL(loadFinished(bool)), this, SLOT(webviewFinished())); +} + +void AuthWidgetPrivate::setProgress(AuthWidget::Progress progress) +{ + Q_Q(AuthWidget); + + this->progress = progress; + Q_EMIT q->progress(progress); +} + + +void AuthWidgetPrivate::emitError(const KGoogle::Error errCode, const QString& msg) +{ + Q_Q(AuthWidget); + + label->setVisible(true); + webview->setVisible(false); + progressbar->setVisible(false); + + label->setText("" + msg + ""); + + Q_EMIT q->error(errCode, msg); + setProgress(AuthWidget::Error); +} + + +void AuthWidgetPrivate::webviewUrlChanged(const QUrl &url) +{ + /* Access token here - hide browser and tell user to wait until we + * finish the authentication process ourselves */ + if (url.host() == "accounts.google.com" && url.path() == "/o/oauth2/approval") { + webview->setVisible(false); + progressbar->setVisible(false); + label->setVisible(true); + + setProgress(AuthWidget::TokensRetrieval); + } +} + +void AuthWidgetPrivate::webviewFinished() +{ + QUrl url = webview->url(); + + if (url.host() == "accounts.google.com" && url.path() == "/ServiceLogin") { + if (username.isEmpty() && password.isEmpty()) { + return; + } + + QWebFrame *frame = webview->page()->mainFrame(); + if (!username.isEmpty()) { + QWebElement email = frame->findFirstElement("input#Email"); + if (!email.isNull()) { + email.setAttribute("value", username); + } + } + + if (!password.isEmpty()) { + QWebElement passd = frame->findFirstElement("input#Passwd"); + if (!passd.isNull()) { + passd.setAttribute("value", password); + } + } + + return; + } + + if (url.host() == "accounts.google.com" && url.path() == "/o/oauth2/approval") { + QWebElement el = webview->page()->mainFrame()->findFirstElement("textarea"); + if (el.isNull()) { + emitError(KGoogle::AuthError, i18n("Parsing token page failed.")); + return; + } + + QString token = el.toInnerXml(); + if (token.isEmpty()) { + emitError(KGoogle::AuthError, i18n("Failed to obtain token.")); + return; + } + + QNetworkAccessManager *nam = new KIO::Integration::AccessManager(this); + QNetworkRequest request; + + connect(nam, SIGNAL(finished(QNetworkReply*)), + this, SLOT(networkRequestFinished(QNetworkReply*))); + connect(nam, SIGNAL(finished(QNetworkReply*)), + nam, SLOT(deleteLater())); + + request.setUrl(QUrl("https://accounts.google.com/o/oauth2/token")); + request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); + + QUrl params; + params.addQueryItem("client_id", KGoogle::Auth::instance()->apiKey()); + params.addQueryItem("client_secret", KGoogle::Auth::instance()->apiSecret()); + params.addQueryItem("code", token); + params.addQueryItem("redirect_uri", "urn:ietf:wg:oauth:2.0:oob"); + params.addQueryItem("grant_type", "authorization_code"); + +#ifdef DEBUG_RAWDATA + kDebug() << "Authorizing token:" << params; +#endif + + nam->post(request, params.encodedQuery()); + } +} + +void AuthWidgetPrivate::networkRequestFinished(QNetworkReply* reply) +{ + if (reply->error() != QNetworkReply::NoError) { + emitError(KGoogle::AuthError, i18n("Authentization failed:\n%1", reply->errorString())); + return; + } + + QJson::Parser parser; + bool ok; + + QVariantMap parsed_data = parser.parse(reply->readAll(), &ok).toMap(); + if (!ok) { + emitError(KGoogle::AuthError, i18n("Failed to parse server response.")); + return; + } + +#ifdef DEBUG_RAWDATA + kDebug() << "Retrieved new tokens pair:" << parsed_data; +#endif + + account->setAccessToken(parsed_data["access_token"].toString()); + account->setRefreshToken(parsed_data["refresh_token"].toString()); + + KGoogle::AccessManager *gam = new KGoogle::AccessManager; + connect(gam, SIGNAL(replyReceived(KGoogle::Reply*)), + this, SLOT(accountInfoReceived(KGoogle::Reply*))); + connect(gam, SIGNAL(replyReceived(KGoogle::Reply*)), + gam, SLOT(deleteLater())); + connect(gam, SIGNAL(error(KGoogle::Error,QString)), + this, SLOT(emitError(KGoogle::Error,QString))); + + KGoogle::Request *request; + request = new KGoogle::Request(KGoogle::Services::AccountInfo::fetchUrl(), + KGoogle::Request::Fetch, "AccountInfo", account); + + gam->sendRequest(request); +} + +void AuthWidgetPrivate::accountInfoReceived(KGoogle::Reply* reply) +{ + Q_Q(AuthWidget); + + if (reply->error() != KGoogle::OK) { + emitError(reply->error(), reply->errorString()); + return; + } + + QList< KGoogle::Object* > data = reply->replyData(); + KGoogle::Objects::AccountInfo *accountInfo = static_cast< KGoogle::Objects::AccountInfo* >(data.first()); + + account->setAccountName(accountInfo->email()); + + delete reply; + + Q_EMIT q->authenticated(account); + setProgress(AuthWidget::Finished); +} diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/ui/authwidget_p.h akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/ui/authwidget_p.h --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/libkgoogle/ui/authwidget_p.h 1970-01-01 00:00:00.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/libkgoogle/ui/authwidget_p.h 2012-06-16 02:20:58.000000000 +0000 @@ -0,0 +1,77 @@ +/* + LibKGoogle - AuthWidgetPrivate + Copyright (C) 2012 Dan Vratil + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + + +#ifndef AUTHWIDGET_P_H +#define AUTHWIDGET_P_H + +#include + +#include "ui/authwidget.h" + +#include +#include +#include +#include + +class QNetworkReply; + +namespace KGoogle { + +class Reply; + +class AuthWidgetPrivate: public QObject { + + Q_OBJECT + + public: + explicit AuthWidgetPrivate(AuthWidget *parent); + + virtual ~AuthWidgetPrivate(); + + bool showProgressBar; + QString username; + QString password; + KGoogle::Account::Ptr account; + AuthWidget::Progress progress; + + QProgressBar *progressbar; + QVBoxLayout *vbox; + QWebView *webview; + QLabel *label; + + private Q_SLOTS: + void emitError(const KGoogle::Error errCode, const QString &msg); + void webviewUrlChanged(const QUrl &url); + void webviewFinished(); + + void networkRequestFinished(QNetworkReply *reply); + void accountInfoReceived(KGoogle::Reply *reply); + + private: + void setupUi(); + void setProgress(AuthWidget::Progress progress); + + AuthWidget *q_ptr; + Q_DECLARE_PUBLIC(AuthWidget); +}; + +} /* namespace KGoogle */ + + +#endif // AUTHWIDGET_P_H diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/LibKGoogleConfig.cmake.in akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/LibKGoogleConfig.cmake.in --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/LibKGoogleConfig.cmake.in 1970-01-01 00:00:00.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/LibKGoogleConfig.cmake.in 2012-06-16 02:20:58.000000000 +0000 @@ -0,0 +1,25 @@ +# Do not modify this file. Any change will be overwritten by CMake. + +# Config file for LibKGoogle. This file will define: +# LibKGoogle_INCLUDE_DIR - The LibKGoogle include directory +# LibKGoogle_LIBRARY - The library needed to use LibKGoogle +# LibKGoogle_VERSION - The LibKGoogle version + +get_filename_component(_currentDir ${CMAKE_CURRENT_LIST_FILE} PATH) # The current directory +get_filename_component(rootDir ${_currentDir}/@relInstallDir@ ABSOLUTE) # The install prefix + +# The library version +set(LibKGoogle_VERSION_MAJOR @KGOOGLE_VERSION_MAJOR@) +set(LibKGoogle_VERSION_MINOR @KGOOGLE_VERSION_MINOR@) +set(LibKGoogle_VERSION_RELEASE @KGOOGLE_VERSION_RELEASE@) +set(LibKGoogle_VERSION ${LibKGoogle_VERSION_MAJOR}.${LibKGoogle_VERSION_MINOR}.${LibKGoogle_VERSION_RELEASE}) + +# Include directory +set(LibKGoogle_INSTALL_PREFIX "${rootDir}") +set(LibKGoogle_INCLUDE_DIR "@INCLUDE_INSTALL_DIR@") + +# import the exported targets +include(${_currentDir}/LibKGoogleTargetsWithPrefix.cmake) + +# Set the library variable +set(LibKGoogle_LIBRARY kgoogle) diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/Messages.sh akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/Messages.sh --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/Messages.sh 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/Messages.sh 2012-06-16 02:20:58.000000000 +0000 @@ -1,4 +1,4 @@ #! /usr/bin/env bash $EXTRACTRC `find . -name \*.ui -o -name \*.kcfg` >> rc.cpp || exit 11 -$XGETTEXT `find . -name \*.cpp | grep -v '/tests/'` -o $podir/akonadi_akonadi-google_resource.pot +$XGETTEXT `find . -name \*.cpp | grep -v '/tests/'` -o $podir/libkgoogle.pot rm -f rc.cpp diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/README akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/README --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/README 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/README 2012-06-16 02:20:58.000000000 +0000 @@ -1,17 +1,14 @@ -Akonadi Google +LibKGoogle ======================== -Akonadi Google is a set of Akonadi resources providing access -to various Google services like Google Contacts or Google Calendar -from KDE PIM applications. - +LibKGoogle is a C++ library that implements APIs for various Google +services, including Google Contacts, Google Calendars and Google Tasks. Dependencies: ------------- - KDE Libraries >= 4.7.0 - KDEPIM Libraries >= 4.6 (version >= 4.4 supported with -DUSE_KCAL=TRUE switch, see below) - QJSON - - libxslt - Boost (when using -DUSE_KCAL=TRUE switch) @@ -25,10 +22,6 @@ # As root: make install -To disable calendar resource, use -DBUILD_CALENDAR=OFF. -To disable contacts resource, use -DBUILD_CONTACTS=OFF. -To disable tasks resource, use -DBUILD_TASKS=OFF. - BUGS: ----- Submit bugs and feature requests to KDE bugzilla, product libkgoogle: @@ -40,4 +33,4 @@ ---------------------------------------- If you want to use this resources with KDEPIM Libraries >= 4.4, you can run cmake with -DUSE_KCAL=TRUE. This switch will enable backwards compatibility with old KDEPIM Libraries by using obsolete KCal API -instead of new KCalCore API. During compilation you will see lot of deprecation warning, but it's OK. \ No newline at end of file +instead of new KCalCore API. During compilation you will see lot of deprecation warning, but it's OK. diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/rfc/rfc2445.txt akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/rfc/rfc2445.txt --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/rfc/rfc2445.txt 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/rfc/rfc2445.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,8291 +0,0 @@ - - - - - - -Network Working Group F. Dawson -Request for Comments: 2445 Lotus -Category: Standards Track D. Stenerson - Microsoft - November 1998 - - - Internet Calendaring and Scheduling Core Object Specification - (iCalendar) - -Status of this Memo - - This document specifies an Internet standards track protocol for the - Internet community, and requests discussion and suggestions for - improvements. Please refer to the current edition of the "Internet - Official Protocol Standards" (STD 1) for the standardization state - and status of this protocol. Distribution of this memo is unlimited. - -Copyright Notice - - Copyright (C) The Internet Society (1998). All Rights Reserved. - -Abstract - - There is a clear need to provide and deploy interoperable calendaring - and scheduling services for the Internet. Current group scheduling - and Personal Information Management (PIM) products are being extended - for use across the Internet, today, in proprietary ways. This memo - has been defined to provide the definition of a common format for - openly exchanging calendaring and scheduling information across the - Internet. - - This memo is formatted as a registration for a MIME media type per - [RFC 2048]. However, the format in this memo is equally applicable - for use outside of a MIME message content type. - - The proposed media type value is 'text/calendar'. This string would - label a media type containing calendaring and scheduling information - encoded as text characters formatted in a manner outlined below. - - This MIME media type provides a standard content type for capturing - calendar event, to-do and journal entry information. It also can be - used to convey free/busy time information. The content type is - suitable as a MIME message entity that can be transferred over MIME - based email systems, using HTTP or some other Internet transport. In - - - - - - -Dawson & Stenerson Standards Track [Page 1] - -RFC 2445 iCalendar November 1998 - - - addition, the content type is useful as an object for interactions - between desktop applications using the operating system clipboard, - drag/drop or file systems capabilities. - - This memo is based on the earlier work of the vCalendar specification - for the exchange of personal calendaring and scheduling information. - In order to avoid confusion with this referenced work, this memo is - to be known as the iCalendar specification. - - This memo defines the format for specifying iCalendar object methods. - An iCalendar object method is a set of usage constraints for the - iCalendar object. For example, these methods might define scheduling - messages that request an event be scheduled, reply to an event - request, send a cancellation notice for an event, modify or replace - the definition of an event, provide a counter proposal for an - original event request, delegate an event request to another - individual, request free or busy time, reply to a free or busy time - request, or provide similar scheduling messages for a to-do or - journal entry calendar component. The iCalendar Transport-indendent - Interoperability Protocol (iTIP) defined in [ITIP] is one such - scheduling protocol. - -Table of Contents - - 1 Introduction.....................................................5 - 2 Basic Grammar and Conventions....................................6 - 2.1 Formatting Conventions .......................................7 - 2.2 Related Memos ................................................8 - 2.3 International Considerations .................................8 - 3 Registration Information.........................................8 - 3.1 Content Type .................................................8 - 3.2 Parameters ...................................................9 - 3.3 Content Header Fields .......................................10 - 3.4 Encoding Considerations .....................................10 - 3.5 Security Considerations .....................................10 - 3.6 Interoperability Considerations .............................11 - 3.7 Applications Which Use This Media Type ......................11 - 3.8 Additional Information ......................................11 - 3.9 Magic Numbers ...............................................11 - 3.10 File Extensions ............................................11 - 3.11 Contact for Further Information: ...........................12 - 3.12 Intended Usage .............................................12 - 3.13 Authors/Change Controllers .................................12 - 4 iCalendar Object Specification..................................13 - 4.1 Content Lines ...............................................13 - 4.1.1 List and Field Separators ................................16 - 4.1.2 Multiple Values ..........................................16 - 4.1.3 Binary Content ...........................................16 - - - -Dawson & Stenerson Standards Track [Page 2] - -RFC 2445 iCalendar November 1998 - - - 4.1.4 Character Set ............................................17 - 4.2 Property Parameters .........................................17 - 4.2.1 Alternate Text Representation ............................18 - 4.2.2 Common Name ..............................................19 - 4.2.3 Calendar User Type .......................................20 - 4.2.4 Delegators ...............................................20 - 4.2.5 Delegatees ...............................................21 - 4.2.6 Directory Entry Reference ................................21 - 4.2.7 Inline Encoding ..........................................22 - 4.2.8 Format Type ..............................................23 - 4.2.9 Free/Busy Time Type ......................................23 - 4.2.10 Language ................................................24 - 4.2.11 Group or List Membership ................................25 - 4.2.12 Participation Status ....................................25 - 4.2.13 Recurrence Identifier Range .............................27 - 4.2.14 Alarm Trigger Relationship ..............................27 - 4.2.15 Relationship Type .......................................28 - 4.2.16 Participation Role ......................................29 - 4.2.17 RSVP Expectation ........................................29 - 4.2.18 Sent By .................................................30 - 4.2.19 Time Zone Identifier ....................................30 - 4.2.20 Value Data Types ........................................32 - 4.3 Property Value Data Types ...................................32 - 4.3.1 Binary ...................................................33 - 4.3.2 Boolean ..................................................33 - 4.3.3 Calendar User Address ....................................34 - 4.3.4 Date .....................................................34 - 4.3.5 Date-Time ................................................35 - 4.3.6 Duration .................................................37 - 4.3.7 Float ....................................................38 - 4.3.8 Integer ..................................................38 - 4.3.9 Period of Time ...........................................39 - 4.3.10 Recurrence Rule .........................................40 - 4.3.11 Text ....................................................45 - 4.3.12 Time ....................................................47 - 4.3.13 URI .....................................................49 - 4.3.14 UTC Offset ..............................................49 - 4.4 iCalendar Object ............................................50 - 4.5 Property ....................................................51 - 4.6 Calendar Components .........................................51 - 4.6.1 Event Component ..........................................52 - 4.6.2 To-do Component ..........................................55 - 4.6.3 Journal Component ........................................56 - 4.6.4 Free/Busy Component ......................................58 - 4.6.5 Time Zone Component ......................................60 - 4.6.6 Alarm Component ..........................................67 - 4.7 Calendar Properties .........................................73 - 4.7.1 Calendar Scale ...........................................73 - - - -Dawson & Stenerson Standards Track [Page 3] - -RFC 2445 iCalendar November 1998 - - - 4.7.2 Method ...................................................74 - 4.7.3 Product Identifier .......................................75 - 4.7.4 Version ..................................................76 - 4.8 Component Properties ........................................77 - 4.8.1 Descriptive Component Properties .........................77 - 4.8.1.1 Attachment ...........................................77 - 4.8.1.2 Categories ...........................................78 - 4.8.1.3 Classification .......................................79 - 4.8.1.4 Comment ..............................................80 - 4.8.1.5 Description ..........................................81 - 4.8.1.6 Geographic Position ..................................82 - 4.8.1.7 Location .............................................84 - 4.8.1.8 Percent Complete .....................................85 - 4.8.1.9 Priority .............................................85 - 4.8.1.10 Resources ...........................................87 - 4.8.1.11 Status ..............................................88 - 4.8.1.12 Summary .............................................89 - 4.8.2 Date and Time Component Properties .......................90 - 4.8.2.1 Date/Time Completed ..................................90 - 4.8.2.2 Date/Time End ........................................91 - 4.8.2.3 Date/Time Due ........................................92 - 4.8.2.4 Date/Time Start ......................................93 - 4.8.2.5 Duration .............................................94 - 4.8.2.6 Free/Busy Time .......................................95 - 4.8.2.7 Time Transparency ....................................96 - 4.8.3 Time Zone Component Properties ...........................97 - 4.8.3.1 Time Zone Identifier .................................97 - 4.8.3.2 Time Zone Name .......................................98 - 4.8.3.3 Time Zone Offset From ................................99 - 4.8.3.4 Time Zone Offset To .................................100 - 4.8.3.5 Time Zone URL .......................................101 - 4.8.4 Relationship Component Properties .......................102 - 4.8.4.1 Attendee ............................................102 - 4.8.4.2 Contact .............................................104 - 4.8.4.3 Organizer ...........................................106 - 4.8.4.4 Recurrence ID .......................................107 - 4.8.4.5 Related To ..........................................109 - 4.8.4.6 Uniform Resource Locator ............................110 - 4.8.4.7 Unique Identifier ...................................111 - 4.8.5 Recurrence Component Properties .........................112 - 4.8.5.1 Exception Date/Times ................................112 - 4.8.5.2 Exception Rule ......................................114 - 4.8.5.3 Recurrence Date/Times ...............................115 - 4.8.5.4 Recurrence Rule .....................................117 - 4.8.6 Alarm Component Properties ..............................126 - 4.8.6.1 Action ..............................................126 - 4.8.6.2 Repeat Count ........................................126 - 4.8.6.3 Trigger .............................................127 - - - -Dawson & Stenerson Standards Track [Page 4] - -RFC 2445 iCalendar November 1998 - - - 4.8.7 Change Management Component Properties ..................129 - 4.8.7.1 Date/Time Created ...................................129 - 4.8.7.2 Date/Time Stamp .....................................130 - 4.8.7.3 Last Modified .......................................131 - 4.8.7.4 Sequence Number .....................................131 - 4.8.8 Miscellaneous Component Properties ......................133 - 4.8.8.1 Non-standard Properties .............................133 - 4.8.8.2 Request Status ......................................134 - 5 iCalendar Object Examples......................................136 - 6 Recommended Practices..........................................140 - 7 Registration of Content Type Elements..........................141 - 7.1 Registration of New and Modified iCalendar Object Methods ..141 - 7.2 Registration of New Properties .............................141 - 7.2.1 Define the property .....................................142 - 7.2.2 Post the Property definition ............................143 - 7.2.3 Allow a comment period ..................................143 - 7.2.4 Submit the property for approval ........................143 - 7.3 Property Change Control ....................................143 - 8 References.....................................................144 - 9 Acknowledgments................................................145 - 10 Authors' and Chairs' Addresses................................146 - 11 Full Copyright Statement......................................148 - -1 Introduction - - The use of calendaring and scheduling has grown considerably in the - last decade. Enterprise and inter-enterprise business has become - dependent on rapid scheduling of events and actions using this - information technology. However, the longer term growth of - calendaring and scheduling, is currently limited by the lack of - Internet standards for the message content types that are central to - these knowledgeware applications. This memo is intended to progress - the level of interoperability possible between dissimilar calendaring - and scheduling applications. This memo defines a MIME content type - for exchanging electronic calendaring and scheduling information. The - Internet Calendaring and Scheduling Core Object Specification, or - iCalendar, allows for the capture and exchange of information - normally stored within a calendaring and scheduling application; such - as a Personal Information Manager (PIM) or a Group Scheduling - product. - - The iCalendar format is suitable as an exchange format between - applications or systems. The format is defined in terms of a MIME - content type. This will enable the object to be exchanged using - several transports, including but not limited to SMTP, HTTP, a file - system, desktop interactive protocols such as the use of a memory- - based clipboard or drag/drop interactions, point-to-point - asynchronous communication, wired-network transport, or some form of - - - -Dawson & Stenerson Standards Track [Page 5] - -RFC 2445 iCalendar November 1998 - - - unwired transport such as infrared might also be used. - - The memo also provides for the definition of iCalendar object methods - that will map this content type to a set of messages for supporting - calendaring and scheduling operations such as requesting, replying - to, modifying, and canceling meetings or appointments, to-dos and - journal entries. The iCalendar object methods can be used to define - other calendaring and scheduling operations such a requesting for and - replying with free/busy time data. Such a scheduling protocol is - defined in the iCalendar Transport-independent Interoperability - Protocol (iTIP) defined in [ITIP]. - - The memo also includes a formal grammar for the content type based on - the Internet ABNF defined in [RFC 2234]. This ABNF is required for - the implementation of parsers and to serve as the definitive - reference when ambiguities or questions arise in interpreting the - descriptive prose definition of the memo. - -2 Basic Grammar and Conventions - - The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", - "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" and - "OPTIONAL" in this document are to be interoperated as described in - [RFC 2119]. - - This memo makes use of both a descriptive prose and a more formal - notation for defining the calendaring and scheduling format. - - The notation used in this memo is the ABNF notation of [RFC 2234]. - Readers intending on implementing this format defined in this memo - should be familiar with this notation in order to properly interpret - the specifications of this memo. - - All numeric and hexadecimal values used in this memo are given in - decimal notation. - - All names of properties, property parameters, enumerated property - values and property parameter values are case-insensitive. However, - all other property values are case-sensitive, unless otherwise - stated. - - Note: All indented editorial notes, such as this one, are - intended to provide the reader with additional information. The - information is not essential to the building of an - implementation conformant with this memo. The information is - provided to highlight a particular feature or characteristic of - the memo. - - - - -Dawson & Stenerson Standards Track [Page 6] - -RFC 2445 iCalendar November 1998 - - - The format for the iCalendar object is based on the syntax of the - [RFC 2425] content type. While the iCalendar object is not a profile - of the [RFC 2425] content type, it does reuse a number of the - elements from the [RFC 2425] specification. - -2.1 Formatting Conventions - - The mechanisms defined in this memo are defined in prose. Many of the - terms used to describe these have common usage that is different than - the standards usage of this memo. In order to reference within this - memo elements of the calendaring and scheduling model, core object - (this memo) or interoperability protocol [ITIP] some formatting - conventions have been used. Calendaring and scheduling roles are - referred to in quoted-strings of text with the first character of - each word in upper case. For example, "Organizer" refers to a role of - a "Calendar User" within the scheduling protocol defined by [ITIP]. - Calendar components defined by this memo are referred to with - capitalized, quoted-strings of text. All calendar components start - with the letter "V". For example, "VEVENT" refers to the event - calendar component, "VTODO" refers to the to-do calendar component - and "VJOURNAL" refers to the daily journal calendar component. - Scheduling methods defined by [ITIP] are referred to with - capitalized, quoted-strings of text. For example, "REQUEST" refers to - the method for requesting a scheduling calendar component be created - or modified, "REPLY" refers to the method a recipient of a request - uses to update their status with the "Organizer" of the calendar - component. - - The properties defined by this memo are referred to with capitalized, - quoted-strings of text, followed by the word "property". For example, - "ATTENDEE" property refers to the iCalendar property used to convey - the calendar address of a calendar user. Property parameters defined - by this memo are referred to with lowercase, quoted-strings of text, - followed by the word "parameter". For example, "value" parameter - refers to the iCalendar property parameter used to override the - default data type for a property value. Enumerated values defined by - this memo are referred to with capitalized text, either alone or - followed by the word "value". For example, the "MINUTELY" value can - be used with the "FREQ" component of the "RECUR" data type to specify - repeating components based on an interval of one minute or more. - - - - - - - - - - - -Dawson & Stenerson Standards Track [Page 7] - -RFC 2445 iCalendar November 1998 - - -2.2 Related Memos - - Implementers will need to be familiar with several other memos that, - along with this memo, form a framework for Internet calendaring and - scheduling standards. This memo, [ICAL], specifies a core - specification of objects, data types, properties and property - parameters. - - [ITIP] - specifies an interoperability protocol for scheduling - between different implementations; - - [IMIP] specifies an Internet email binding for [ITIP]. - - This memo does not attempt to repeat the specification of concepts or - definitions from these other memos. Where possible, references are - made to the memo that provides for the specification of these - concepts or definitions. - -2.3 International Considerations - - In the rest of this document, descriptions of characters are of the - form "character name (codepoint)", where "codepoint" is from the US- - ASCII character set. The "character name" is the authoritative - description; (codepoint) is a reference to that character in US-ASCII - or US-ASCII compatible sets (for example the ISO-8859-x family, UTF- - 8, ISO-2022-xx, KOI8-R). If a non-US-ASCII compatible character set - is used, appropriate code-point from that character set MUST be - chosen instead. Use of non-US-ASCII-compatible character sets is NOT - recommended. - -3 Registration Information - - The Calendaring and Scheduling Core Object Specification is intended - for use as a MIME content type. However, the implementation of the - memo is in no way limited solely as a MIME content type. - -3.1 Content Type - - The following text is intended to register this memo as the MIME - content type "text/calendar". - - To: ietf-types@uninett.no - - Subject: Registration of MIME content type text/calendar. - - MIME media type name: text - - MIME subtype name: calendar - - - -Dawson & Stenerson Standards Track [Page 8] - -RFC 2445 iCalendar November 1998 - - -3.2 Parameters - - Required parameters: none - - Optional parameters: charset, method, component and optinfo - - The "charset" parameter is defined in [RFC 2046] for other body - parts. It is used to identify the default character set used within - the body part. - - The "method" parameter is used to convey the iCalendar object method - or transaction semantics for the calendaring and scheduling - information. It also is an identifier for the restricted set of - properties and values that the iCalendar object consists of. The - parameter is to be used as a guide for applications interpreting the - information contained within the body part. It SHOULD NOT be used to - exclude or require particular pieces of information unless the - identified method definition specifically calls for this behavior. - Unless specifically forbidden by a particular method definition, a - text/calendar content type can contain any set of properties - permitted by the Calendaring and Scheduling Core Object - Specification. The "method" parameter MUST be the same value as that - specified in the "METHOD" component property in the iCalendar object. - If one is present, the other MUST also be present. - - The value for the "method" parameter is defined as follows: - - method = 1*(ALPHA / DIGIT / "-") - ; IANA registered iCalendar object method - - The "component" parameter conveys the type of iCalendar calendar - component within the body part. If the iCalendar object contains more - than one calendar component type, then multiple component parameters - MUST be specified. - - The value for the "component" parameter is defined as follows: - - component = ("VEVENT" / "VTODO" / "VJOURNAL" / "VFREEBUSY" - / "VTIMEZONE" / x-name / iana-token) - - The "optinfo" parameter conveys optional information about the - iCalendar object within the body part. This parameter can only - specify semantics already specified by the iCalendar object and that - can be otherwise determined by parsing the body part. In addition, - the optional information specified by this parameter MUST be - consistent with that information specified by the iCalendar object. - For example, it can be used to convey the "Attendee" response status - to a meeting request. The parameter value consists of a string value. - - - -Dawson & Stenerson Standards Track [Page 9] - -RFC 2445 iCalendar November 1998 - - - The parameter can be specified multiple times. - - This parameter MAY only specify semantics already specified by the - iCalendar object and that can be otherwise determined by parsing the - body part. - - The value for the "optinfo" parameter is defined as follows: - - optinfo = infovalue / qinfovalue - - infovalue = iana-token / x-name - - qinfovalue = DQUOTE (infovalue) DQUOTE - -3.3 Content Header Fields - - Optional content header fields: Any header fields defined by [RFC - 2045]. - -3.4 Encoding Considerations - - This MIME content type can contain 8bit characters, so the use of - quoted-printable or BASE64 MIME content-transfer-encodings might be - necessary when iCalendar objects are transferred across protocols - restricted to the 7bit repertoire. Note that a text valued property - in the content entity can also have content encoding of special - characters using a BACKSLASH character (US-ASCII decimal 92) - escapement technique. This means that content values can end up - encoded twice. - -3.5 Security Considerations - - SPOOFING - - In this memo, the "Organizer" is the only person - authorized to make changes to an existing "VEVENT", "VTODO", - "VJOURNAL" calendar component and redistribute the updates to the - "Attendees". An iCalendar object that maliciously changes or cancels - an existing "VEVENT", "VTODO" or "VJOURNAL" or "VFREEBUSY" calendar - component might be constructed by someone other than the "Organizer" - and sent to the "Attendees". In addition in this memo, other than the - "Organizer", an "Attendee" of a "VEVENT", "VTODO", "VJOURNAL" - calendar component is the only other person authorized to update any - parameter associated with their "ATTENDEE" property and send it to - the "Organizer". An iCalendar object that maliciously changes the - "ATTENDEE" parameters can be constructed by someone other than the - real "Attendee" and sent to the "Organizer". - - - - - - -Dawson & Stenerson Standards Track [Page 10] - -RFC 2445 iCalendar November 1998 - - - PROCEDURAL ALARMS - - An iCalendar object can be created that - contains a "VEVENT" and "VTODO" calendar component with "VALARM" - calendar components. The "VALARM" calendar component can be of type - PROCEDURE and can have an attachment containing some sort of - executable program. Implementations that incorporate these types of - alarms are subject to any virus or malicious attack that might occur - as a result of executing the attachment. - - ATTACHMENTS - - An iCalendar object can include references to Uniform - Resource Locators that can be programmed resources. - - Implementers and users of this memo should be aware of the network - security implications of accepting and parsing such information. In - addition, the security considerations observed by implementations of - electronic mail systems should be followed for this memo. - -3.6 Interoperability Considerations - - This MIME content type is intended to define a common format for - conveying calendaring and scheduling information between different - systems. It is heavily based on the earlier [VCAL] industry - specification. - -3.7 Applications Which Use This Media Type - - This content-type is designed for widespread use by Internet - calendaring and scheduling applications. In addition, applications in - the workflow and document management area might find this content- - type applicable. The [ITIP] and [IMIP] Internet protocols directly - use this content-type also. Future work on an Internet calendar - access protocol will utilize this content-type too. - -3.8 Additional Information - - This memo defines this content-type. - -3.9 Magic Numbers - - None. - -3.10 File Extensions - - The file extension of "ics" is to be used to designate a file - containing (an arbitrary set of) calendaring and scheduling - information consistent with this MIME content type. - - - - - - -Dawson & Stenerson Standards Track [Page 11] - -RFC 2445 iCalendar November 1998 - - - The file extension of "ifb" is to be used to designate a file - containing free or busy time information consistent with this MIME - content type. - - Macintosh file type codes: The file type code of "iCal" is to be used - in Apple MacIntosh operating system environments to designate a file - containing calendaring and scheduling information consistent with - this MIME media type. - - The file type code of "iFBf" is to be used in Apple MacIntosh - operating system environments to designate a file containing free or - busy time information consistent with this MIME media type. - -3.11 Contact for Further Information: - - Frank Dawson - 6544 Battleford Drive - Raleigh, NC 27613-3502 - 919-676-9515 (Telephone) - 919-676-9564 (Data/Facsimile) - Frank_Dawson@Lotus.com (Internet Mail) - - Derik Stenerson - One Microsoft Way - Redmond, WA 98052-6399 - 425-936-5522 (Telephone) - 425-936-7329 (Facsimile) - deriks@microsoft.com (Internet Mail) - -3.12 Intended Usage - - COMMON - -3.13 Authors/Change Controllers - - Frank Dawson - 6544 Battleford Drive - Raleigh, NC 27613-3502 - 919-676-9515 (Telephone) - 919-676-9564 (Data/Facsimile) - Frank_Dawson@Lotus.com (Internet Mail) - - Derik Stenerson - One Microsoft Way - Redmond, WA 98052-6399 - 425-936-5522 (Telephone) - 425-936-7329 (Facsimile) - deriks@microsoft.com (Internet Mail) - - - -Dawson & Stenerson Standards Track [Page 12] - -RFC 2445 iCalendar November 1998 - - -4 iCalendar Object Specification - - The following sections define the details of a Calendaring and - Scheduling Core Object Specification. This information is intended to - be an integral part of the MIME content type registration. In - addition, this information can be used independent of such content - registration. In particular, this memo has direct applicability for - use as a calendaring and scheduling exchange format in file-, memory- - or network-based transport mechanisms. - -4.1 Content Lines - - The iCalendar object is organized into individual lines of text, - called content lines. Content lines are delimited by a line break, - which is a CRLF sequence (US-ASCII decimal 13, followed by US-ASCII - decimal 10). - - Lines of text SHOULD NOT be longer than 75 octets, excluding the line - break. Long content lines SHOULD be split into a multiple line - representations using a line "folding" technique. That is, a long - line can be split between any two characters by inserting a CRLF - immediately followed by a single linear white space character (i.e., - SPACE, US-ASCII decimal 32 or HTAB, US-ASCII decimal 9). Any sequence - of CRLF followed immediately by a single linear white space character - is ignored (i.e., removed) when processing the content type. - - For example the line: - - DESCRIPTION:This is a long description that exists on a long line. - - Can be represented as: - - DESCRIPTION:This is a lo - ng description - that exists on a long line. - - The process of moving from this folded multiple line representation - to its single line representation is called "unfolding". Unfolding is - accomplished by removing the CRLF character and the linear white - space character that immediately follows. - - When parsing a content line, folded lines MUST first be unfolded - according to the unfolding procedure described above. When generating - a content line, lines longer than 75 octets SHOULD be folded - according to the folding procedure described above. - - - - - - -Dawson & Stenerson Standards Track [Page 13] - -RFC 2445 iCalendar November 1998 - - - The content information associated with an iCalendar object is - formatted using a syntax similar to that defined by [RFC 2425]. That - is, the content information consists of CRLF-separated content lines. - - The following notation defines the lines of content in an iCalendar - object: - - contentline = name *(";" param ) ":" value CRLF - ; This ABNF is just a general definition for an initial parsing - ; of the content line into its property name, parameter list, - ; and value string - - ; When parsing a content line, folded lines MUST first - ; be unfolded according to the unfolding procedure - ; described above. When generating a content line, lines - ; longer than 75 octets SHOULD be folded according to - ; the folding procedure described above. - - name = x-name / iana-token - - iana-token = 1*(ALPHA / DIGIT / "-") - ; iCalendar identifier registered with IANA - - x-name = "X-" [vendorid "-"] 1*(ALPHA / DIGIT / "-") - ; Reservered for experimental use. Not intended for use in - ; released products. - - vendorid = 3*(ALPHA / DIGIT) ;Vendor identification - - param = param-name "=" param-value - *("," param-value) - ; Each property defines the specific ABNF for the parameters - ; allowed on the property. Refer to specific properties for - ; precise parameter ABNF. - - param-name = iana-token / x-token - - param-value = paramtext / quoted-string - - paramtext = *SAFE-CHAR - - value = *VALUE-CHAR - - quoted-string = DQUOTE *QSAFE-CHAR DQUOTE - - NON-US-ASCII = %x80-F8 - ; Use restricted by charset parameter - ; on outer MIME object (UTF-8 preferred) - - - -Dawson & Stenerson Standards Track [Page 14] - -RFC 2445 iCalendar November 1998 - - - QSAFE-CHAR = WSP / %x21 / %x23-7E / NON-US-ASCII - ; Any character except CTLs and DQUOTE - - SAFE-CHAR = WSP / %x21 / %x23-2B / %x2D-39 / %x3C-7E - / NON-US-ASCII - ; Any character except CTLs, DQUOTE, ";", ":", "," - - VALUE-CHAR = WSP / %x21-7E / NON-US-ASCII - ; Any textual character - - CR = %x0D - ; carriage return - - LF = %x0A - ; line feed - - CRLF = CR LF - ; Internet standard newline - - CTL = %x00-08 / %x0A-1F / %x7F - ; Controls - - ALPHA = %x41-5A / %x61-7A ; A-Z / a-z - - DIGIT = %x30-39 - ; 0-9 - - DQUOTE = %x22 - ; Quotation Mark - - WSP = SPACE / HTAB - - SPACE = %x20 - - HTAB = %x09 - - The property value component of a content line has a format that is - property specific. Refer to the section describing each property for - a definition of this format. - - All names of properties, property parameters, enumerated property - values and property parameter values are case-insensitive. However, - all other property values are case-sensitive, unless otherwise - stated. - - - - - - - -Dawson & Stenerson Standards Track [Page 15] - -RFC 2445 iCalendar November 1998 - - -4.1.1 List and Field Separators - - Some properties and parameters allow a list of values. Values in a - list of values MUST be separated by a COMMA character (US-ASCII - decimal 44). There is no significance to the order of values in a - list. For those parameter values (such as those that specify URI - values) that are specified in quoted-strings, the individual quoted- - strings are separated by a COMMA character (US-ASCII decimal 44). - - Some property values are defined in terms of multiple parts. These - structured property values MUST have their value parts separated by a - SEMICOLON character (US-ASCII decimal 59). - - Some properties allow a list of parameters. Each property parameter - in a list of property parameters MUST be separated by a SEMICOLON - character (US-ASCII decimal 59). - - Property parameters with values containing a COLON, a SEMICOLON or a - COMMA character MUST be placed in quoted text. - - For example, in the following properties a SEMICOLON is used to - separate property parameters from each other, and a COMMA is used to - separate property values in a value list. - - ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT:MAILTO: - jsmith@host.com - - RDATE;VALUE=DATE:19970304,19970504,19970704,19970904 - -4.1.2 Multiple Values - - Some properties defined in the iCalendar object can have multiple - values. The general rule for encoding multi-valued items is to simply - create a new content line for each value, including the property - name. However, it should be noted that some properties support - encoding multiple values in a single property by separating the - values with a COMMA character (US-ASCII decimal 44). Individual - property definitions should be consulted for determining whether a - specific property allows multiple values and in which of these two - forms. - -4.1.3 Binary Content - - Binary content information in an iCalendar object SHOULD be - referenced using a URI within a property value. That is the binary - content information SHOULD be placed in an external MIME entity that - can be referenced by a URI from within the iCalendar object. In - applications where this is not feasible, binary content information - - - -Dawson & Stenerson Standards Track [Page 16] - -RFC 2445 iCalendar November 1998 - - - can be included within an iCalendar object, but only after first - encoding it into text using the "BASE64" encoding method defined in - [RFC 2045]. Inline binary contact SHOULD only be used in applications - whose special circumstances demand that an iCalendar object be - expressed as a single entity. A property containing inline binary - content information MUST specify the "ENCODING" property parameter. - Binary content information placed external to the iCalendar object - MUST be referenced by a uniform resource identifier (URI). - - The following example specifies an "ATTACH" property that references - an attachment external to the iCalendar object with a URI reference: - - ATTACH:http://xyz.com/public/quarterly-report.doc - - The following example specifies an "ATTACH" property with inline - binary encoded content information: - - ATTACH;FMTTYPE=image/basic;ENCODING=BASE64;VALUE=BINARY: - MIICajCCAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1U - EBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlIENvbW11bmljYXRpb25zIE - <...remainder of "BASE64" encoded binary data...> - -4.1.4 Character Set - - There is not a property parameter to declare the character set used - in a property value. The default character set for an iCalendar - object is UTF-8 as defined in [RFC 2279]. - - The "charset" Content-Type parameter can be used in MIME transports - to specify any other IANA registered character set. - -4.2 Property Parameters - - A property can have attributes associated with it. These "property - parameters" contain meta-information about the property or the - property value. Property parameters are provided to specify such - information as the location of an alternate text representation for a - property value, the language of a text property value, the data type - of the property value and other attributes. - - Property parameter values that contain the COLON (US-ASCII decimal - 58), SEMICOLON (US-ASCII decimal 59) or COMMA (US-ASCII decimal 44) - character separators MUST be specified as quoted-string text values. - Property parameter values MUST NOT contain the DOUBLE-QUOTE (US-ASCII - decimal 22) character. The DOUBLE-QUOTE (US-ASCII decimal 22) - character is used as a delimiter for parameter values that contain - restricted characters or URI text. For example: - - - - -Dawson & Stenerson Standards Track [Page 17] - -RFC 2445 iCalendar November 1998 - - - DESCRIPTION;ALTREP="http://www.wiz.org":The Fall'98 Wild Wizards - Conference - - Las Vegas, NV, USA - - Property parameter values that are not in quoted strings are case - insensitive. - - The general property parameters defined by this memo are defined by - the following notation: - - parameter = altrepparam ; Alternate text representation - / cnparam ; Common name - / cutypeparam ; Calendar user type - / delfromparam ; Delegator - / deltoparam ; Delegatee - / dirparam ; Directory entry - / encodingparam ; Inline encoding - / fmttypeparam ; Format type - / fbtypeparam ; Free/busy time type - / languageparam ; Language for text - / memberparam ; Group or list membership - / partstatparam ; Participation status - / rangeparam ; Recurrence identifier range - / trigrelparam ; Alarm trigger relationship - / reltypeparam ; Relationship type - / roleparam ; Participation role - / rsvpparam ; RSVP expectation - / sentbyparam ; Sent by - / tzidparam ; Reference to time zone object - / valuetypeparam ; Property value data type - / ianaparam - ; Some other IANA registered iCalendar parameter. - / xparam - ; A non-standard, experimental parameter. - - ianaparam = iana-token "=" param-value *("," param-value) - - xparam =x-name "=" param-value *("," param-value) - -4.2.1 Alternate Text Representation - - Parameter Name: ALTREP - - Purpose: To specify an alternate text representation for the property - value. - - Format Definition: The property parameter is defined by the following - notation: - - - - -Dawson & Stenerson Standards Track [Page 18] - -RFC 2445 iCalendar November 1998 - - - altrepparam = "ALTREP" "=" DQUOTE uri DQUOTE - - Description: The parameter specifies a URI that points to an - alternate representation for a textual property value. A property - specifying this parameter MUST also include a value that reflects the - default representation of the text value. The individual URI - parameter values MUST each be specified in a quoted-string. - - Example: - - DESCRIPTION;ALTREP="CID:":Project - XYZ Review Meeting will include the following agenda items: (a) - Market Overview, (b) Finances, (c) Project Management - - The "ALTREP" property parameter value might point to a "text/html" - content portion. - - Content-Type:text/html - Content-Id: - - -

Project XYZ Review Meeting will include the following - agenda items:

  1. Market - Overview
  2. Finances
  3. Project Management

- - -4.2.2 Common Name - - Parameter Name: CN - - Purpose: To specify the common name to be associated with the - calendar user specified by the property. - - Format Definition: The property parameter is defined by the following - notation: - - cnparam = "CN" "=" param-value - - Description: This parameter can be specified on properties with a - CAL-ADDRESS value type. The parameter specifies the common name to be - associated with the calendar user specified by the property. The - parameter value is text. The parameter value can be used for display - text to be associated with the calendar address specified by the - property. - - - - - - - -Dawson & Stenerson Standards Track [Page 19] - -RFC 2445 iCalendar November 1998 - - - Example: - - ORGANIZER;CN="John Smith":MAILTO:jsmith@host.com - -4.2.3 Calendar User Type - - Parameter Name: CUTYPE - - Purpose: To specify the type of calendar user specified by the - property. - - Format Definition: The property parameter is defined by the following - notation: - - cutypeparam = "CUTYPE" "=" - ("INDIVIDUAL" ; An individual - / "GROUP" ; A group of individuals - / "RESOURCE" ; A physical resource - / "ROOM" ; A room resource - / "UNKNOWN" ; Otherwise not known - / x-name ; Experimental type - / iana-token) ; Other IANA registered - ; type - ; Default is INDIVIDUAL - - Description: This parameter can be specified on properties with a - CAL-ADDRESS value type. The parameter identifies the type of calendar - user specified by the property. If not specified on a property that - allows this parameter, the default is INDIVIDUAL. - - Example: - - ATTENDEE;CUTYPE=GROUP:MAILTO:ietf-calsch@imc.org - -4.2.4 Delegators - - Parameter Name: DELEGATED-FROM - - Purpose: To specify the calendar users that have delegated their - participation to the calendar user specified by the property. - - Format Definition: The property parameter is defined by the following - notation: - - delfromparam = "DELEGATED-FROM" "=" DQUOTE cal-address DQUOTE - *("," DQUOTE cal-address DQUOTE) - - - - - -Dawson & Stenerson Standards Track [Page 20] - -RFC 2445 iCalendar November 1998 - - - Description: This parameter can be specified on properties with a - CAL-ADDRESS value type. This parameter can be specified on a property - that has a value type of calendar address. This parameter specifies - those calendar uses that have delegated their participation in a - group scheduled event or to-do to the calendar user specified by the - property. The value MUST be a MAILTO URI as defined in [RFC 1738]. - The individual calendar address parameter values MUST each be - specified in a quoted-string. - - Example: - - ATTENDEE;DELEGATED-FROM="MAILTO:jsmith@host.com":MAILTO: - jdoe@host.com - -4.2.5 Delegatees - - Parameter Name: DELEGATED-TO - - Purpose: To specify the calendar users to whom the calendar user - specified by the property has delegated participation. - - Format Definition: The property parameter is defined by the following - notation: - - deltoparam = "DELEGATED-TO" "=" DQUOTE cal-address DQUOTE - *("," DQUOTE cal-address DQUOTE) - - Description: This parameter can be specified on properties with a - CAL-ADDRESS value type. This parameter specifies those calendar users - whom have been delegated participation in a group scheduled event or - to-do by the calendar user specified by the property. The value MUST - be a MAILTO URI as defined in [RFC 1738]. The individual calendar - address parameter values MUST each be specified in a quoted-string. - - Example: - - ATTENDEE;DELEGATED-TO="MAILTO:jdoe@host.com","MAILTO:jqpublic@ - host.com":MAILTO:jsmith@host.com - -4.2.6 Directory Entry Reference - - Parameter Name: DIR - - Purpose: To specify reference to a directory entry associated with - the calendar user specified by the property. - - Format Definition: The property parameter is defined by the following - notation: - - - -Dawson & Stenerson Standards Track [Page 21] - -RFC 2445 iCalendar November 1998 - - - dirparam = "DIR" "=" DQUOTE uri DQUOTE - - Description: This parameter can be specified on properties with a - CAL-ADDRESS value type. The parameter specifies a reference to the - directory entry associated with the calendar user specified by the - property. The parameter value is a URI. The individual URI parameter - values MUST each be specified in a quoted-string. - - Example: - - ORGANIZER;DIR="ldap://host.com:6666/o=eDABC%20Industries,c=3DUS?? - (cn=3DBJim%20Dolittle)":MAILTO:jimdo@host1.com - -4.2.7 Inline Encoding - - Parameter Name: ENCODING - - Purpose: To specify an alternate inline encoding for the property - value. - - Format Definition: The property parameter is defined by the following - notation: - - encodingparam = "ENCODING" "=" - ("8BIT" - ; "8bit" text encoding is defined in [RFC 2045] - / "BASE64" - ; "BASE64" binary encoding format is defined in [RFC 2045] - / iana-token - ; Some other IANA registered iCalendar encoding type - / x-name) - ; A non-standard, experimental encoding type - - Description: The property parameter identifies the inline encoding - used in a property value. The default encoding is "8BIT", - corresponding to a property value consisting of text. The "BASE64" - encoding type corresponds to a property value encoded using the - "BASE64" encoding defined in [RFC 2045]. - - If the value type parameter is ";VALUE=BINARY", then the inline - encoding parameter MUST be specified with the value - ";ENCODING=BASE64". - - - - - - - - - -Dawson & Stenerson Standards Track [Page 22] - -RFC 2445 iCalendar November 1998 - - - Example: - - ATTACH;FMTYPE=IMAGE/JPEG;ENCODING=BASE64;VALUE=BINARY:MIICajC - CAdOgAwIBAgICBEUwDQYJKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDA - qBgNVBAoTI05ldHNjYXBlIENvbW11bmljYXRpb25zIENvcnBvcmF0aW9uMRw - <...remainder of "BASE64" encoded binary data...> - -4.2.8 Format Type - - Parameter Name: FMTTYPE - - Purpose: To specify the content type of a referenced object. - - Format Definition: The property parameter is defined by the following - notation: - - fmttypeparam = "FMTTYPE" "=" iana-token - ; A IANA registered content type - / x-name - ; A non-standard content type - - Description: This parameter can be specified on properties that are - used to reference an object. The parameter specifies the content type - of the referenced object. For example, on the "ATTACH" property, a - FTP type URI value does not, by itself, necessarily convey the type - of content associated with the resource. The parameter value MUST be - the TEXT for either an IANA registered content type or a non-standard - content type. - - Example: - - ATTACH;FMTTYPE=application/binary:ftp://domain.com/pub/docs/ - agenda.doc - -4.2.9 Free/Busy Time Type - - Parameter Name: FBTYPE - - Purpose: To specify the free or busy time type. - - Format Definition: The property parameter is defined by the following - notation: - - fbtypeparam = "FBTYPE" "=" ("FREE" / "BUSY" - / "BUSY-UNAVAILABLE" / "BUSY-TENTATIVE" - / x-name - ; Some experimental iCalendar data type. - / iana-token) - - - -Dawson & Stenerson Standards Track [Page 23] - -RFC 2445 iCalendar November 1998 - - - ; Some other IANA registered iCalendar data type. - - Description: The parameter specifies the free or busy time type. The - value FREE indicates that the time interval is free for scheduling. - The value BUSY indicates that the time interval is busy because one - or more events have been scheduled for that interval. The value - BUSY-UNAVAILABLE indicates that the time interval is busy and that - the interval can not be scheduled. The value BUSY-TENTATIVE indicates - that the time interval is busy because one or more events have been - tentatively scheduled for that interval. If not specified on a - property that allows this parameter, the default is BUSY. - - Example: The following is an example of this parameter on a FREEBUSY - property. - - FREEBUSY;FBTYPE=BUSY:19980415T133000Z/19980415T170000Z - -4.2.10 Language - - Parameter Name: LANGUAGE - - Purpose: To specify the language for text values in a property or - property parameter. - - Format Definition: The property parameter is defined by the following - notation: - - languageparam = "LANGUAGE" "=" language - - language = - - Description: This parameter can be specified on properties with a - text value type. The parameter identifies the language of the text in - the property or property parameter value. The value of the "language" - property parameter is that defined in [RFC 1766]. - - For transport in a MIME entity, the Content-Language header field can - be used to set the default language for the entire body part. - Otherwise, no default language is assumed. - - Example: - - SUMMARY;LANGUAGE=us-EN:Company Holiday Party - - LOCATION;LANGUAGE=en:Germany - LOCATION;LANGUAGE=no:Tyskland - - - - - -Dawson & Stenerson Standards Track [Page 24] - -RFC 2445 iCalendar November 1998 - - - The following example makes use of the Quoted-Printable encoding in - order to represent non-ASCII characters. - - LOCATION;LANGUAGE=da:K=F8benhavn - LOCATION;LANGUAGE=en:Copenhagen - -4.2.11 Group or List Membership - - Parameter Name: MEMBER - - Purpose: To specify the group or list membership of the calendar user - specified by the property. - - Format Definition: The property parameter is defined by the following - notation: - - memberparam = "MEMBER" "=" DQUOTE cal-address DQUOTE - *("," DQUOTE cal-address DQUOTE) - - Description: This parameter can be specified on properties with a - CAL-ADDRESS value type. The parameter identifies the groups or list - membership for the calendar user specified by the property. The - parameter value either a single calendar address in a quoted-string - or a COMMA character (US-ASCII decimal 44) list of calendar - addresses, each in a quoted-string. The individual calendar address - parameter values MUST each be specified in a quoted-string. - - Example: - - ATTENDEE;MEMBER="MAILTO:ietf-calsch@imc.org":MAILTO:jsmith@host.com - - ATTENDEE;MEMBER="MAILTO:projectA@host.com","MAILTO:projectB@host. - com":MAILTO:janedoe@host.com - -4.2.12 Participation Status - - Parameter Name: PARTSTAT - - Purpose: To specify the participation status for the calendar user - specified by the property. - - Format Definition: The property parameter is defined by the following - notation: - - partstatparam = "PARTSTAT" "=" - ("NEEDS-ACTION" ; Event needs action - / "ACCEPTED" ; Event accepted - / "DECLINED" ; Event declined - - - -Dawson & Stenerson Standards Track [Page 25] - -RFC 2445 iCalendar November 1998 - - - / "TENTATIVE" ; Event tentatively - ; accepted - / "DELEGATED" ; Event delegated - / x-name ; Experimental status - / iana-token) ; Other IANA registered - ; status - ; These are the participation statuses for a "VEVENT". Default is - ; NEEDS-ACTION - partstatparam /= "PARTSTAT" "=" - ("NEEDS-ACTION" ; To-do needs action - / "ACCEPTED" ; To-do accepted - / "DECLINED" ; To-do declined - / "TENTATIVE" ; To-do tentatively - ; accepted - / "DELEGATED" ; To-do delegated - / "COMPLETED" ; To-do completed. - ; COMPLETED property has - ;date/time completed. - / "IN-PROCESS" ; To-do in process of - ; being completed - / x-name ; Experimental status - / iana-token) ; Other IANA registered - ; status - ; These are the participation statuses for a "VTODO". Default is - ; NEEDS-ACTION - - partstatparam /= "PARTSTAT" "=" - ("NEEDS-ACTION" ; Journal needs action - / "ACCEPTED" ; Journal accepted - / "DECLINED" ; Journal declined - / x-name ; Experimental status - / iana-token) ; Other IANA registered - ; status - ; These are the participation statuses for a "VJOURNAL". Default is - ; NEEDS-ACTION - - Description: This parameter can be specified on properties with a - CAL-ADDRESS value type. The parameter identifies the participation - status for the calendar user specified by the property value. The - parameter values differ depending on whether they are associated with - a group scheduled "VEVENT", "VTODO" or "VJOURNAL". The values MUST - match one of the values allowed for the given calendar component. If - not specified on a property that allows this parameter, the default - value is NEEDS-ACTION. - - Example: - - ATTENDEE;PARTSTAT=DECLINED:MAILTO:jsmith@host.com - - - -Dawson & Stenerson Standards Track [Page 26] - -RFC 2445 iCalendar November 1998 - - -4.2.13 Recurrence Identifier Range - - Parameter Name: RANGE - - Purpose: To specify the effective range of recurrence instances from - the instance specified by the recurrence identifier specified by the - property. - - Format Definition: The property parameter is defined by the following - notation: - - rangeparam = "RANGE" "=" ("THISANDPRIOR" - ; To specify all instances prior to the recurrence identifier - / "THISANDFUTURE") - ; To specify the instance specified by the recurrence identifier - ; and all subsequent recurrence instances - - Description: The parameter can be specified on a property that - specifies a recurrence identifier. The parameter specifies the - effective range of recurrence instances that is specified by the - property. The effective range is from the recurrence identified - specified by the property. If this parameter is not specified an - allowed property, then the default range is the single instance - specified by the recurrence identifier value of the property. The - parameter value can be "THISANDPRIOR" to indicate a range defined by - the recurrence identified value of the property and all prior - instances. The parameter value can also be "THISANDFUTURE" to - indicate a range defined by the recurrence identifier and all - subsequent instances. - - Example: - - RECURRENCE-ID;RANGE=THISANDPRIOR:19980401T133000Z - -4.2.14 Alarm Trigger Relationship - - Parameter Name: RELATED - - Purpose: To specify the relationship of the alarm trigger with - respect to the start or end of the calendar component. - - Format Definition: The property parameter is defined by the following - notation: - - trigrelparam = "RELATED" "=" - ("START" ; Trigger off of start - / "END") ; Trigger off of end - - - - -Dawson & Stenerson Standards Track [Page 27] - -RFC 2445 iCalendar November 1998 - - - Description: The parameter can be specified on properties that - specify an alarm trigger with a DURATION value type. The parameter - specifies whether the alarm will trigger relative to the start or end - of the calendar component. The parameter value START will set the - alarm to trigger off the start of the calendar component; the - parameter value END will set the alarm to trigger off the end of the - calendar component. If the parameter is not specified on an allowable - property, then the default is START. - - Example: - - TRIGGER;RELATED=END:PT5M - -4.2.15 Relationship Type - - Parameter Name: RELTYPE - - Purpose: To specify the type of hierarchical relationship associated - with the calendar component specified by the property. - - Format Definition: The property parameter is defined by the following - notation: - - reltypeparam = "RELTYPE" "=" - ("PARENT" ; Parent relationship. Default. - / "CHILD" ; Child relationship - / "SIBLING ; Sibling relationship - / iana-token ; Some other IANA registered - ; iCalendar relationship type - / x-name) ; A non-standard, experimental - ; relationship type - - Description: This parameter can be specified on a property that - references another related calendar. The parameter specifies the - hierarchical relationship type of the calendar component referenced - by the property. The parameter value can be PARENT, to indicate that - the referenced calendar component is a superior of calendar - component; CHILD to indicate that the referenced calendar component - is a subordinate of the calendar component; SIBLING to indicate that - the referenced calendar component is a peer of the calendar - component. If this parameter is not specified on an allowable - property, the default relationship type is PARENT. - - Example: - - RELATED-TO;RELTYPE=SIBLING:<19960401-080045-4000F192713@host.com> - - - - - -Dawson & Stenerson Standards Track [Page 28] - -RFC 2445 iCalendar November 1998 - - -4.2.16 Participation Role - - Parameter Name: ROLE - - Purpose: To specify the participation role for the calendar user - specified by the property. - - Format Definition: The property parameter is defined by the following - notation: - - roleparam = "ROLE" "=" - ("CHAIR" ; Indicates chair of the - ; calendar entity - / "REQ-PARTICIPANT" ; Indicates a participant whose - ; participation is required - / "OPT-PARTICIPANT" ; Indicates a participant whose - ; participation is optional - / "NON-PARTICIPANT" ; Indicates a participant who is - ; copied for information - ; purposes only - / x-name ; Experimental role - / iana-token) ; Other IANA role - ; Default is REQ-PARTICIPANT - - Description: This parameter can be specified on properties with a - CAL-ADDRESS value type. The parameter specifies the participation - role for the calendar user specified by the property in the group - schedule calendar component. If not specified on a property that - allows this parameter, the default value is REQ-PARTICIPANT. - - Example: - - ATTENDEE;ROLE=CHAIR:MAILTO:mrbig@host.com - -4.2.17 RSVP Expectation - - Parameter Name: RSVP - - Purpose: To specify whether there is an expectation of a favor of a - reply from the calendar user specified by the property value. - - Format Definition: The property parameter is defined by the following - notation: - - rsvpparam = "RSVP" "=" ("TRUE" / "FALSE") - ; Default is FALSE - - - - - -Dawson & Stenerson Standards Track [Page 29] - -RFC 2445 iCalendar November 1998 - - - Description: This parameter can be specified on properties with a - CAL-ADDRESS value type. The parameter identifies the expectation of a - reply from the calendar user specified by the property value. This - parameter is used by the "Organizer" to request a participation - status reply from an "Attendee" of a group scheduled event or to-do. - If not specified on a property that allows this parameter, the - default value is FALSE. - - Example: - - ATTENDEE;RSVP=TRUE:MAILTO:jsmith@host.com - -4.2.18 Sent By - - Parameter Name: SENT-BY - - Purpose: To specify the calendar user that is acting on behalf of the - calendar user specified by the property. - - Format Definition: The property parameter is defined by the following - notation: - - sentbyparam = "SENT-BY" "=" DQUOTE cal-address DQUOTE - - Description: This parameter can be specified on properties with a - CAL-ADDRESS value type. The parameter specifies the calendar user - that is acting on behalf of the calendar user specified by the - property. The parameter value MUST be a MAILTO URI as defined in [RFC - 1738]. The individual calendar address parameter values MUST each be - specified in a quoted-string. - - Example: - - ORGANIZER;SENT-BY:"MAILTO:sray@host.com":MAILTO:jsmith@host.com - -4.2.19 Time Zone Identifier - - Parameter Name: TZID - - Purpose: To specify the identifier for the time zone definition for a - time component in the property value. - - Format Definition: This property parameter is defined by the - following notation: - - tzidparam = "TZID" "=" [tzidprefix] paramtext CRLF - - tzidprefix = "/" - - - -Dawson & Stenerson Standards Track [Page 30] - -RFC 2445 iCalendar November 1998 - - - Description: The parameter MUST be specified on the "DTSTART", - "DTEND", "DUE", "EXDATE" and "RDATE" properties when either a DATE- - TIME or TIME value type is specified and when the value is not either - a UTC or a "floating" time. Refer to the DATE-TIME or TIME value type - definition for a description of UTC and "floating time" formats. This - property parameter specifies a text value which uniquely identifies - the "VTIMEZONE" calendar component to be used when evaluating the - time portion of the property. The value of the TZID property - parameter will be equal to the value of the TZID property for the - matching time zone definition. An individual "VTIMEZONE" calendar - component MUST be specified for each unique "TZID" parameter value - specified in the iCalendar object. - - The parameter MUST be specified on properties with a DATE-TIME value - if the DATE-TIME is not either a UTC or a "floating" time. - - The presence of the SOLIDUS character (US-ASCII decimal 47) as a - prefix, indicates that this TZID represents a unique ID in a globally - defined time zone registry (when such registry is defined). - - Note: This document does not define a naming convention for time - zone identifiers. Implementers may want to use the naming - conventions defined in existing time zone specifications such as - the public-domain Olson database [TZ]. The specification of - globally unique time zone identifiers is not addressed by this - document and is left for future study. - - The following are examples of this property parameter: - - DTSTART;TZID=US-Eastern:19980119T020000 - - DTEND;TZID=US-Eastern:19980119T030000 - - The TZID property parameter MUST NOT be applied to DATE-TIME or TIME - properties whose time values are specified in UTC. - - The use of local time in a DATE-TIME or TIME value without the TZID - property parameter is to be interpreted as a local time value, - regardless of the existence of "VTIMEZONE" calendar components in the - iCalendar object. - - For more information see the sections on the data types DATE-TIME and - TIME. - - - - - - - - -Dawson & Stenerson Standards Track [Page 31] - -RFC 2445 iCalendar November 1998 - - -4.2.20 Value Data Types - - Parameter Name: VALUE - - Purpose: To explicitly specify the data type format for a property - value. - - Format Definition: The "VALUE" property parameter is defined by the - following notation: - - valuetypeparam = "VALUE" "=" valuetype - - valuetype = ("BINARY" - / "BOOLEAN" - / "CAL-ADDRESS" - / "DATE" - / "DATE-TIME" - / "DURATION" - / "FLOAT" - / "INTEGER" - / "PERIOD" - / "RECUR" - / "TEXT" - / "TIME" - / "URI" - / "UTC-OFFSET" - / x-name - ; Some experimental iCalendar data type. - / iana-token) - ; Some other IANA registered iCalendar data type. - - Description: The parameter specifies the data type and format of the - property value. The property values MUST be of a single value type. - For example, a "RDATE" property cannot have a combination of DATE- - TIME and TIME value types. - - If the property's value is the default value type, then this - parameter need not be specified. However, if the property's default - value type is overridden by some other allowable value type, then - this parameter MUST be specified. - -4.3 Property Value Data Types - - The properties in an iCalendar object are strongly typed. The - definition of each property restricts the value to be one of the - value data types, or simply value types, defined in this section. The - value type for a property will either be specified implicitly as the - default value type or will be explicitly specified with the "VALUE" - - - -Dawson & Stenerson Standards Track [Page 32] - -RFC 2445 iCalendar November 1998 - - - parameter. If the value type of a property is one of the alternate - valid types, then it MUST be explicitly specified with the "VALUE" - parameter. - -4.3.1 Binary - - Value Name: BINARY - - Purpose: This value type is used to identify properties that contain - a character encoding of inline binary data. For example, an inline - attachment of an object code might be included in an iCalendar - object. - - Formal Definition: The value type is defined by the following - notation: - - binary = *(4b-char) [b-end] - ; A "BASE64" encoded character string, as defined by [RFC 2045]. - - b-end = (2b-char "==") / (3b-char "=") - - b-char = ALPHA / DIGIT / "+" / "/" - - Description: Property values with this value type MUST also include - the inline encoding parameter sequence of ";ENCODING=BASE64". That - is, all inline binary data MUST first be character encoded using the - "BASE64" encoding method defined in [RFC 2045]. No additional content - value encoding (i.e., BACKSLASH character encoding) is defined for - this value type. - - Example: The following is an abridged example of a "BASE64" encoded - binary value data. - - ATTACH;VALUE=BINARY;ENCODING=BASE64:MIICajCCAdOgAwIBAgICBEUwDQY - JKoZIhvcNAQEEBQAwdzELMAkGA1UEBhMCVVMxLDAqBgNVBAoTI05ldHNjYXBlI - ENvbW11bmljYXRpb25zIENvcnBvcmF0aW9uMRwwGgYDVQQLExNJbmZv - <...remainder of "BASE64" encoded binary data...> - -4.3.2 Boolean - - Value Name: BOOLEAN - - Purpose: This value type is used to identify properties that contain - either a "TRUE" or "FALSE" Boolean value. - - Formal Definition: The value type is defined by the following - notation: - - - - -Dawson & Stenerson Standards Track [Page 33] - -RFC 2445 iCalendar November 1998 - - - boolean = "TRUE" / "FALSE" - - Description: These values are case insensitive text. No additional - content value encoding (i.e., BACKSLASH character encoding) is - defined for this value type. - - Example: The following is an example of a hypothetical property that - has a BOOLEAN value type: - - GIBBERISH:TRUE - -4.3.3 Calendar User Address - - Value Name: CAL-ADDRESS - - Purpose: This value type is used to identify properties that contain - a calendar user address. - - Formal Definition: The value type is as defined by the following - notation: - - cal-address = uri - - Description: The value is a URI as defined by [RFC 1738] or any other - IANA registered form for a URI. When used to address an Internet - email transport address for a calendar user, the value MUST be a - MAILTO URI, as defined by [RFC 1738]. No additional content value - encoding (i.e., BACKSLASH character encoding) is defined for this - value type. - - Example: - - ATTENDEE:MAILTO:jane_doe@host.com - -4.3.4 Date - - Value Name: DATE - - Purpose: This value type is used to identify values that contain a - calendar date. - - Formal Definition: The value type is defined by the following - notation: - - date = date-value - - date-value = date-fullyear date-month date-mday - date-fullyear = 4DIGIT - - - -Dawson & Stenerson Standards Track [Page 34] - -RFC 2445 iCalendar November 1998 - - - date-month = 2DIGIT ;01-12 - date-mday = 2DIGIT ;01-28, 01-29, 01-30, 01-31 - ;based on month/year - - Description: If the property permits, multiple "date" values are - specified as a COMMA character (US-ASCII decimal 44) separated list - of values. The format for the value type is expressed as the [ISO - 8601] complete representation, basic format for a calendar date. The - textual format specifies a four-digit year, two-digit month, and - two-digit day of the month. There are no separator characters between - the year, month and day component text. - - No additional content value encoding (i.e., BACKSLASH character - encoding) is defined for this value type. - - Example: The following represents July 14, 1997: - - 19970714 - -4.3.5 Date-Time - - Value Name: DATE-TIME - - Purpose: This value type is used to identify values that specify a - precise calendar date and time of day. - - Formal Definition: The value type is defined by the following - notation: - - date-time = date "T" time ;As specified in the date and time - ;value definitions - - Description: If the property permits, multiple "date-time" values are - specified as a COMMA character (US-ASCII decimal 44) separated list - of values. No additional content value encoding (i.e., BACKSLASH - character encoding) is defined for this value type. - - The "DATE-TIME" data type is used to identify values that contain a - precise calendar date and time of day. The format is based on the - [ISO 8601] complete representation, basic format for a calendar date - and time of day. The text format is a concatenation of the "date", - followed by the LATIN CAPITAL LETTER T character (US-ASCII decimal - 84) time designator, followed by the "time" format. - - The "DATE-TIME" data type expresses time values in three forms: - - The form of date and time with UTC offset MUST NOT be used. For - example, the following is not valid for a date-time value: - - - -Dawson & Stenerson Standards Track [Page 35] - -RFC 2445 iCalendar November 1998 - - - DTSTART:19980119T230000-0800 ;Invalid time format - - FORM #1: DATE WITH LOCAL TIME - - The date with local time form is simply a date-time value that does - not contain the UTC designator nor does it reference a time zone. For - example, the following represents Janurary 18, 1998, at 11 PM: - - DTSTART:19980118T230000 - - Date-time values of this type are said to be "floating" and are not - bound to any time zone in particular. They are used to represent the - same hour, minute, and second value regardless of which time zone is - currently being observed. For example, an event can be defined that - indicates that an individual will be busy from 11:00 AM to 1:00 PM - every day, no matter which time zone the person is in. In these - cases, a local time can be specified. The recipient of an iCalendar - object with a property value consisting of a local time, without any - relative time zone information, SHOULD interpret the value as being - fixed to whatever time zone the ATTENDEE is in at any given moment. - This means that two ATTENDEEs, in different time zones, receiving the - same event definition as a floating time, may be participating in the - event at different actual times. Floating time SHOULD only be used - where that is the reasonable behavior. - - In most cases, a fixed time is desired. To properly communicate a - fixed time in a property value, either UTC time or local time with - time zone reference MUST be specified. - - The use of local time in a DATE-TIME value without the TZID property - parameter is to be interpreted as floating time, regardless of the - existence of "VTIMEZONE" calendar components in the iCalendar object. - - FORM #2: DATE WITH UTC TIME - - The date with UTC time, or absolute time, is identified by a LATIN - CAPITAL LETTER Z suffix character (US-ASCII decimal 90), the UTC - designator, appended to the time value. For example, the following - represents January 19, 1998, at 0700 UTC: - - DTSTART:19980119T070000Z - - The TZID property parameter MUST NOT be applied to DATE-TIME - properties whose time values are specified in UTC. - - FORM #3: DATE WITH LOCAL TIME AND TIME ZONE REFERENCE - - - - - -Dawson & Stenerson Standards Track [Page 36] - -RFC 2445 iCalendar November 1998 - - - The date and local time with reference to time zone information is - identified by the use the TZID property parameter to reference the - appropriate time zone definition. TZID is discussed in detail in the - section on Time Zone. For example, the following represents 2 AM in - New York on Janurary 19, 1998: - - DTSTART;TZID=US-Eastern:19980119T020000 - - Example: The following represents July 14, 1997, at 1:30 PM in New - York City in each of the three time formats, using the "DTSTART" - property. - - DTSTART:19970714T133000 ;Local time - DTSTART:19970714T173000Z ;UTC time - DTSTART;TZID=US-Eastern:19970714T133000 ;Local time and time - ; zone reference - - A time value MUST ONLY specify 60 seconds when specifying the - periodic "leap second" in the time value. For example: - - COMPLETED:19970630T235960Z - -4.3.6 Duration - - Value Name: DURATION - - Purpose: This value type is used to identify properties that contain - a duration of time. - - Formal Definition: The value type is defined by the following - notation: - - dur-value = (["+"] / "-") "P" (dur-date / dur-time / dur-week) - - dur-date = dur-day [dur-time] - dur-time = "T" (dur-hour / dur-minute / dur-second) - dur-week = 1*DIGIT "W" - dur-hour = 1*DIGIT "H" [dur-minute] - dur-minute = 1*DIGIT "M" [dur-second] - dur-second = 1*DIGIT "S" - dur-day = 1*DIGIT "D" - - Description: If the property permits, multiple "duration" values are - specified by a COMMA character (US-ASCII decimal 44) separated list - of values. The format is expressed as the [ISO 8601] basic format for - the duration of time. The format can represent durations in terms of - weeks, days, hours, minutes, and seconds. - - - - -Dawson & Stenerson Standards Track [Page 37] - -RFC 2445 iCalendar November 1998 - - - No additional content value encoding (i.e., BACKSLASH character - encoding) are defined for this value type. - - Example: A duration of 15 days, 5 hours and 20 seconds would be: - - P15DT5H0M20S - - A duration of 7 weeks would be: - - P7W - -4.3.7 Float - - Value Name: FLOAT - - Purpose: This value type is used to identify properties that contain - a real number value. - - Formal Definition: The value type is defined by the following - notation: - - float = (["+"] / "-") 1*DIGIT ["." 1*DIGIT] - - Description: If the property permits, multiple "float" values are - specified by a COMMA character (US-ASCII decimal 44) separated list - of values. - - No additional content value encoding (i.e., BACKSLASH character - encoding) is defined for this value type. - - Example: - - 1000000.0000001 - 1.333 - -3.14 - -4.3.8 Integer - - Value Name:INTEGER - - Purpose: This value type is used to identify properties that contain - a signed integer value. - - Formal Definition: The value type is defined by the following - notation: - - integer = (["+"] / "-") 1*DIGIT - - - - -Dawson & Stenerson Standards Track [Page 38] - -RFC 2445 iCalendar November 1998 - - - Description: If the property permits, multiple "integer" values are - specified by a COMMA character (US-ASCII decimal 44) separated list - of values. The valid range for "integer" is -2147483648 to - 2147483647. If the sign is not specified, then the value is assumed - to be positive. - - No additional content value encoding (i.e., BACKSLASH character - encoding) is defined for this value type. - - Example: - - 1234567890 - -1234567890 - +1234567890 - 432109876 - -4.3.9 Period of Time - - Value Name: PERIOD - - Purpose: This value type is used to identify values that contain a - precise period of time. - - Formal Definition: The data type is defined by the following - notation: - - period = period-explicit / period-start - - period-explicit = date-time "/" date-time - ; [ISO 8601] complete representation basic format for a period of - ; time consisting of a start and end. The start MUST be before the - ; end. - - period-start = date-time "/" dur-value - ; [ISO 8601] complete representation basic format for a period of - ; time consisting of a start and positive duration of time. - - Description: If the property permits, multiple "period" values are - specified by a COMMA character (US-ASCII decimal 44) separated list - of values. There are two forms of a period of time. First, a period - of time is identified by its start and its end. This format is - expressed as the [ISO 8601] complete representation, basic format for - "DATE-TIME" start of the period, followed by a SOLIDUS character - (US-ASCII decimal 47), followed by the "DATE-TIME" of the end of the - period. The start of the period MUST be before the end of the period. - Second, a period of time can also be defined by a start and a - positive duration of time. The format is expressed as the [ISO 8601] - complete representation, basic format for the "DATE-TIME" start of - - - -Dawson & Stenerson Standards Track [Page 39] - -RFC 2445 iCalendar November 1998 - - - the period, followed by a SOLIDUS character (US-ASCII decimal 47), - followed by the [ISO 8601] basic format for "DURATION" of the period. - - Example: The period starting at 18:00:00 UTC, on January 1, 1997 and - ending at 07:00:00 UTC on January 2, 1997 would be: - - 19970101T180000Z/19970102T070000Z - - The period start at 18:00:00 on January 1, 1997 and lasting 5 hours - and 30 minutes would be: - - 19970101T180000Z/PT5H30M - - No additional content value encoding (i.e., BACKSLASH character - encoding) is defined for this value type. - -4.3.10 Recurrence Rule - - Value Name: RECUR - - Purpose: This value type is used to identify properties that contain - a recurrence rule specification. - - Formal Definition: The value type is defined by the following - notation: - - recur = "FREQ"=freq *( - - ; either UNTIL or COUNT may appear in a 'recur', - ; but UNTIL and COUNT MUST NOT occur in the same 'recur' - - ( ";" "UNTIL" "=" enddate ) / - ( ";" "COUNT" "=" 1*DIGIT ) / - - ; the rest of these keywords are optional, - ; but MUST NOT occur more than once - - ( ";" "INTERVAL" "=" 1*DIGIT ) / - ( ";" "BYSECOND" "=" byseclist ) / - ( ";" "BYMINUTE" "=" byminlist ) / - ( ";" "BYHOUR" "=" byhrlist ) / - ( ";" "BYDAY" "=" bywdaylist ) / - ( ";" "BYMONTHDAY" "=" bymodaylist ) / - ( ";" "BYYEARDAY" "=" byyrdaylist ) / - ( ";" "BYWEEKNO" "=" bywknolist ) / - ( ";" "BYMONTH" "=" bymolist ) / - ( ";" "BYSETPOS" "=" bysplist ) / - ( ";" "WKST" "=" weekday ) / - - - -Dawson & Stenerson Standards Track [Page 40] - -RFC 2445 iCalendar November 1998 - - - ( ";" x-name "=" text ) - ) - - freq = "SECONDLY" / "MINUTELY" / "HOURLY" / "DAILY" - / "WEEKLY" / "MONTHLY" / "YEARLY" - - enddate = date - enddate =/ date-time ;An UTC value - - byseclist = seconds / ( seconds *("," seconds) ) - - seconds = 1DIGIT / 2DIGIT ;0 to 59 - - byminlist = minutes / ( minutes *("," minutes) ) - - minutes = 1DIGIT / 2DIGIT ;0 to 59 - - byhrlist = hour / ( hour *("," hour) ) - - hour = 1DIGIT / 2DIGIT ;0 to 23 - - bywdaylist = weekdaynum / ( weekdaynum *("," weekdaynum) ) - - weekdaynum = [([plus] ordwk / minus ordwk)] weekday - - plus = "+" - - minus = "-" - - ordwk = 1DIGIT / 2DIGIT ;1 to 53 - - weekday = "SU" / "MO" / "TU" / "WE" / "TH" / "FR" / "SA" - ;Corresponding to SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, - ;FRIDAY, SATURDAY and SUNDAY days of the week. - - bymodaylist = monthdaynum / ( monthdaynum *("," monthdaynum) ) - - monthdaynum = ([plus] ordmoday) / (minus ordmoday) - - ordmoday = 1DIGIT / 2DIGIT ;1 to 31 - - byyrdaylist = yeardaynum / ( yeardaynum *("," yeardaynum) ) - - yeardaynum = ([plus] ordyrday) / (minus ordyrday) - - ordyrday = 1DIGIT / 2DIGIT / 3DIGIT ;1 to 366 - - bywknolist = weeknum / ( weeknum *("," weeknum) ) - - - -Dawson & Stenerson Standards Track [Page 41] - -RFC 2445 iCalendar November 1998 - - - weeknum = ([plus] ordwk) / (minus ordwk) - - bymolist = monthnum / ( monthnum *("," monthnum) ) - - monthnum = 1DIGIT / 2DIGIT ;1 to 12 - - bysplist = setposday / ( setposday *("," setposday) ) - - setposday = yeardaynum - - Description: If the property permits, multiple "recur" values are - specified by a COMMA character (US-ASCII decimal 44) separated list - of values. The value type is a structured value consisting of a list - of one or more recurrence grammar parts. Each rule part is defined by - a NAME=VALUE pair. The rule parts are separated from each other by - the SEMICOLON character (US-ASCII decimal 59). The rule parts are not - ordered in any particular sequence. Individual rule parts MUST only - be specified once. - - The FREQ rule part identifies the type of recurrence rule. This rule - part MUST be specified in the recurrence rule. Valid values include - SECONDLY, to specify repeating events based on an interval of a - second or more; MINUTELY, to specify repeating events based on an - interval of a minute or more; HOURLY, to specify repeating events - based on an interval of an hour or more; DAILY, to specify repeating - events based on an interval of a day or more; WEEKLY, to specify - repeating events based on an interval of a week or more; MONTHLY, to - specify repeating events based on an interval of a month or more; and - YEARLY, to specify repeating events based on an interval of a year or - more. - - The INTERVAL rule part contains a positive integer representing how - often the recurrence rule repeats. The default value is "1", meaning - every second for a SECONDLY rule, or every minute for a MINUTELY - rule, every hour for an HOURLY rule, every day for a DAILY rule, - every week for a WEEKLY rule, every month for a MONTHLY rule and - every year for a YEARLY rule. - - The UNTIL rule part defines a date-time value which bounds the - recurrence rule in an inclusive manner. If the value specified by - UNTIL is synchronized with the specified recurrence, this date or - date-time becomes the last instance of the recurrence. If specified - as a date-time value, then it MUST be specified in an UTC time - format. If not present, and the COUNT rule part is also not present, - the RRULE is considered to repeat forever. - - The COUNT rule part defines the number of occurrences at which to - range-bound the recurrence. The "DTSTART" property value, if - - - -Dawson & Stenerson Standards Track [Page 42] - -RFC 2445 iCalendar November 1998 - - - specified, counts as the first occurrence. - - The BYSECOND rule part specifies a COMMA character (US-ASCII decimal - 44) separated list of seconds within a minute. Valid values are 0 to - 59. The BYMINUTE rule part specifies a COMMA character (US-ASCII - decimal 44) separated list of minutes within an hour. Valid values - are 0 to 59. The BYHOUR rule part specifies a COMMA character (US- - ASCII decimal 44) separated list of hours of the day. Valid values - are 0 to 23. - - The BYDAY rule part specifies a COMMA character (US-ASCII decimal 44) - separated list of days of the week; MO indicates Monday; TU indicates - Tuesday; WE indicates Wednesday; TH indicates Thursday; FR indicates - Friday; SA indicates Saturday; SU indicates Sunday. - - Each BYDAY value can also be preceded by a positive (+n) or negative - (-n) integer. If present, this indicates the nth occurrence of the - specific day within the MONTHLY or YEARLY RRULE. For example, within - a MONTHLY rule, +1MO (or simply 1MO) represents the first Monday - within the month, whereas -1MO represents the last Monday of the - month. If an integer modifier is not present, it means all days of - this type within the specified frequency. For example, within a - MONTHLY rule, MO represents all Mondays within the month. - - The BYMONTHDAY rule part specifies a COMMA character (ASCII decimal - 44) separated list of days of the month. Valid values are 1 to 31 or - -31 to -1. For example, -10 represents the tenth to the last day of - the month. - - The BYYEARDAY rule part specifies a COMMA character (US-ASCII decimal - 44) separated list of days of the year. Valid values are 1 to 366 or - -366 to -1. For example, -1 represents the last day of the year - (December 31st) and -306 represents the 306th to the last day of the - year (March 1st). - - The BYWEEKNO rule part specifies a COMMA character (US-ASCII decimal - 44) separated list of ordinals specifying weeks of the year. Valid - values are 1 to 53 or -53 to -1. This corresponds to weeks according - to week numbering as defined in [ISO 8601]. A week is defined as a - seven day period, starting on the day of the week defined to be the - week start (see WKST). Week number one of the calendar year is the - first week which contains at least four (4) days in that calendar - year. This rule part is only valid for YEARLY rules. For example, 3 - represents the third week of the year. - - Note: Assuming a Monday week start, week 53 can only occur when - Thursday is January 1 or if it is a leap year and Wednesday is - January 1. - - - -Dawson & Stenerson Standards Track [Page 43] - -RFC 2445 iCalendar November 1998 - - - The BYMONTH rule part specifies a COMMA character (US-ASCII decimal - 44) separated list of months of the year. Valid values are 1 to 12. - - The WKST rule part specifies the day on which the workweek starts. - Valid values are MO, TU, WE, TH, FR, SA and SU. This is significant - when a WEEKLY RRULE has an interval greater than 1, and a BYDAY rule - part is specified. This is also significant when in a YEARLY RRULE - when a BYWEEKNO rule part is specified. The default value is MO. - - The BYSETPOS rule part specifies a COMMA character (US-ASCII decimal - 44) separated list of values which corresponds to the nth occurrence - within the set of events specified by the rule. Valid values are 1 to - 366 or -366 to -1. It MUST only be used in conjunction with another - BYxxx rule part. For example "the last work day of the month" could - be represented as: - - RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-1 - - Each BYSETPOS value can include a positive (+n) or negative (-n) - integer. If present, this indicates the nth occurrence of the - specific occurrence within the set of events specified by the rule. - - If BYxxx rule part values are found which are beyond the available - scope (ie, BYMONTHDAY=30 in February), they are simply ignored. - - Information, not contained in the rule, necessary to determine the - various recurrence instance start time and dates are derived from the - Start Time (DTSTART) entry attribute. For example, - "FREQ=YEARLY;BYMONTH=1" doesn't specify a specific day within the - month or a time. This information would be the same as what is - specified for DTSTART. - - BYxxx rule parts modify the recurrence in some manner. BYxxx rule - parts for a period of time which is the same or greater than the - frequency generally reduce or limit the number of occurrences of the - recurrence generated. For example, "FREQ=DAILY;BYMONTH=1" reduces the - number of recurrence instances from all days (if BYMONTH tag is not - present) to all days in January. BYxxx rule parts for a period of - time less than the frequency generally increase or expand the number - of occurrences of the recurrence. For example, - "FREQ=YEARLY;BYMONTH=1,2" increases the number of days within the - yearly recurrence set from 1 (if BYMONTH tag is not present) to 2. - - If multiple BYxxx rule parts are specified, then after evaluating the - specified FREQ and INTERVAL rule parts, the BYxxx rule parts are - applied to the current set of evaluated occurrences in the following - order: BYMONTH, BYWEEKNO, BYYEARDAY, BYMONTHDAY, BYDAY, BYHOUR, - BYMINUTE, BYSECOND and BYSETPOS; then COUNT and UNTIL are evaluated. - - - -Dawson & Stenerson Standards Track [Page 44] - -RFC 2445 iCalendar November 1998 - - - Here is an example of evaluating multiple BYxxx rule parts. - - DTSTART;TZID=US-Eastern:19970105T083000 - RRULE:FREQ=YEARLY;INTERVAL=2;BYMONTH=1;BYDAY=SU;BYHOUR=8,9; - BYMINUTE=30 - - First, the "INTERVAL=2" would be applied to "FREQ=YEARLY" to arrive - at "every other year". Then, "BYMONTH=1" would be applied to arrive - at "every January, every other year". Then, "BYDAY=SU" would be - applied to arrive at "every Sunday in January, every other year". - Then, "BYHOUR=8,9" would be applied to arrive at "every Sunday in - January at 8 AM and 9 AM, every other year". Then, "BYMINUTE=30" - would be applied to arrive at "every Sunday in January at 8:30 AM and - 9:30 AM, every other year". Then, lacking information from RRULE, the - second is derived from DTSTART, to end up in "every Sunday in January - at 8:30:00 AM and 9:30:00 AM, every other year". Similarly, if the - BYMINUTE, BYHOUR, BYDAY, BYMONTHDAY or BYMONTH rule part were - missing, the appropriate minute, hour, day or month would have been - retrieved from the "DTSTART" property. - - No additional content value encoding (i.e., BACKSLASH character - encoding) is defined for this value type. - - Example: The following is a rule which specifies 10 meetings which - occur every other day: - - FREQ=DAILY;COUNT=10;INTERVAL=2 - - There are other examples specified in the "RRULE" specification. - -4.3.11 Text - - Value Name: TEXT - - Purpose This value type is used to identify values that contain human - readable text. - - Formal Definition: The character sets supported by this revision of - iCalendar are UTF-8 and US ASCII thereof. The applicability to other - character sets is for future work. The value type is defined by the - following notation. - - text = *(TSAFE-CHAR / ":" / DQUOTE / ESCAPED-CHAR) - ; Folded according to description above - - ESCAPED-CHAR = "\\" / "\;" / "\," / "\N" / "\n") - ; \\ encodes \, \N or \n encodes newline - ; \; encodes ;, \, encodes , - - - -Dawson & Stenerson Standards Track [Page 45] - -RFC 2445 iCalendar November 1998 - - - TSAFE-CHAR = %x20-21 / %x23-2B / %x2D-39 / %x3C-5B - %x5D-7E / NON-US-ASCII - ; Any character except CTLs not needed by the current - ; character set, DQUOTE, ";", ":", "\", "," - - Note: Certain other character sets may require modification of the - above definitions, but this is beyond the scope of this document. - - Description: If the property permits, multiple "text" values are - specified by a COMMA character (US-ASCII decimal 44) separated list - of values. - - The language in which the text is represented can be controlled by - the "LANGUAGE" property parameter. - - An intentional formatted text line break MUST only be included in a - "TEXT" property value by representing the line break with the - character sequence of BACKSLASH (US-ASCII decimal 92), followed by a - LATIN SMALL LETTER N (US-ASCII decimal 110) or a LATIN CAPITAL LETTER - N (US-ASCII decimal 78), that is "\n" or "\N". - - The "TEXT" property values may also contain special characters that - are used to signify delimiters, such as a COMMA character for lists - of values or a SEMICOLON character for structured values. In order to - support the inclusion of these special characters in "TEXT" property - values, they MUST be escaped with a BACKSLASH character. A BACKSLASH - character (US-ASCII decimal 92) in a "TEXT" property value MUST be - escaped with another BACKSLASH character. A COMMA character in a - "TEXT" property value MUST be escaped with a BACKSLASH character - (US-ASCII decimal 92). A SEMICOLON character in a "TEXT" property - value MUST be escaped with a BACKSLASH character (US-ASCII decimal - 92). However, a COLON character in a "TEXT" property value SHALL NOT - be escaped with a BACKSLASH character.Example: A multiple line value - of: - - Project XYZ Final Review - Conference Room - 3B - Come Prepared. - - would be represented as: - - Project XYZ Final Review\nConference Room - 3B\nCome Prepared. - - - - - - - - - -Dawson & Stenerson Standards Track [Page 46] - -RFC 2445 iCalendar November 1998 - - -4.3.12 Time - - Value Name: TIME - - Purpose: This value type is used to identify values that contain a - time of day. - - Formal Definition: The data type is defined by the following - notation: - - time = time-hour time-minute time-second [time-utc] - - time-hour = 2DIGIT ;00-23 - time-minute = 2DIGIT ;00-59 - time-second = 2DIGIT ;00-60 - ;The "60" value is used to account for "leap" seconds. - - time-utc = "Z" - - Description: If the property permits, multiple "time" values are - specified by a COMMA character (US-ASCII decimal 44) separated list - of values. No additional content value encoding (i.e., BACKSLASH - character encoding) is defined for this value type. - - The "TIME" data type is used to identify values that contain a time - of day. The format is based on the [ISO 8601] complete - representation, basic format for a time of day. The text format - consists of a two-digit 24-hour of the day (i.e., values 0-23), two- - digit minute in the hour (i.e., values 0-59), and two-digit seconds - in the minute (i.e., values 0-60). The seconds value of 60 MUST only - to be used to account for "leap" seconds. Fractions of a second are - not supported by this format. - - In parallel to the "DATE-TIME" definition above, the "TIME" data type - expresses time values in three forms: - - The form of time with UTC offset MUST NOT be used. For example, the - following is NOT VALID for a time value: - - 230000-0800 ;Invalid time format - - FORM #1 LOCAL TIME - - The local time form is simply a time value that does not contain the - UTC designator nor does it reference a time zone. For example, 11:00 - PM: - - 230000 - - - -Dawson & Stenerson Standards Track [Page 47] - -RFC 2445 iCalendar November 1998 - - - Time values of this type are said to be "floating" and are not bound - to any time zone in particular. They are used to represent the same - hour, minute, and second value regardless of which time zone is - currently being observed. For example, an event can be defined that - indicates that an individual will be busy from 11:00 AM to 1:00 PM - every day, no matter which time zone the person is in. In these - cases, a local time can be specified. The recipient of an iCalendar - object with a property value consisting of a local time, without any - relative time zone information, SHOULD interpret the value as being - fixed to whatever time zone the ATTENDEE is in at any given moment. - This means that two ATTENDEEs may participate in the same event at - different UTC times; floating time SHOULD only be used where that is - reasonable behavior. - - In most cases, a fixed time is desired. To properly communicate a - fixed time in a property value, either UTC time or local time with - time zone reference MUST be specified. - - The use of local time in a TIME value without the TZID property - parameter is to be interpreted as a local time value, regardless of - the existence of "VTIMEZONE" calendar components in the iCalendar - object. - - FORM #2: UTC TIME - - UTC time, or absolute time, is identified by a LATIN CAPITAL LETTER Z - suffix character (US-ASCII decimal 90), the UTC designator, appended - to the time value. For example, the following represents 07:00 AM - UTC: - - 070000Z - - The TZID property parameter MUST NOT be applied to TIME properties - whose time values are specified in UTC. - - FORM #3: LOCAL TIME AND TIME ZONE REFERENCE - - The local time with reference to time zone information form is - identified by the use the TZID property parameter to reference the - appropriate time zone definition. TZID is discussed in detail in the - section on Time Zone. - - Example: The following represents 8:30 AM in New York in Winter, five - hours behind UTC, in each of the three formats using the "X- - TIMEOFDAY" non-standard property: - - - - - - -Dawson & Stenerson Standards Track [Page 48] - -RFC 2445 iCalendar November 1998 - - - X-TIMEOFDAY:083000 - - X-TIMEOFDAY:133000Z - - X-TIMEOFDAY;TZID=US-Eastern:083000 - -4.3.13 URI - - Value Name: URI - - Purpose: This value type is used to identify values that contain a - uniform resource identifier (URI) type of reference to the property - value. - - Formal Definition: The data type is defined by the following - notation: - - uri = - - Description: This data type might be used to reference binary - information, for values that are large, or otherwise undesirable to - include directly in the iCalendar object. - - The URI value formats in RFC 1738, RFC 2111 and any other IETF - registered value format can be specified. - - Any IANA registered URI format can be used. These include, but are - not limited to, those defined in RFC 1738 and RFC 2111. - - When a property parameter value is a URI value type, the URI MUST be - specified as a quoted-string value. - - No additional content value encoding (i.e., BACKSLASH character - encoding) is defined for this value type. - - Example: The following is a URI for a network file: - - http://host1.com/my-report.txt - -4.3.14 UTC Offset - - Value Name: UTC-OFFSET - - Purpose: This value type is used to identify properties that contain - an offset from UTC to local time. - - Formal Definition: The data type is defined by the following - notation: - - - -Dawson & Stenerson Standards Track [Page 49] - -RFC 2445 iCalendar November 1998 - - - utc-offset = time-numzone ;As defined above in time data type - - time-numzone = ("+" / "-") time-hour time-minute [time- - second] - - Description: The PLUS SIGN character MUST be specified for positive - UTC offsets (i.e., ahead of UTC). The value of "-0000" and "-000000" - are not allowed. The time-second, if present, may not be 60; if - absent, it defaults to zero. - - No additional content value encoding (i.e., BACKSLASH character - encoding) is defined for this value type. - - Example: The following UTC offsets are given for standard time for - New York (five hours behind UTC) and Geneva (one hour ahead of UTC): - - -0500 - - +0100 - -4.4 iCalendar Object - - The Calendaring and Scheduling Core Object is a collection of - calendaring and scheduling information. Typically, this information - will consist of a single iCalendar object. However, multiple - iCalendar objects can be sequentially grouped together. The first - line and last line of the iCalendar object MUST contain a pair of - iCalendar object delimiter strings. The syntax for an iCalendar - object is as follows: - - icalobject = 1*("BEGIN" ":" "VCALENDAR" CRLF - icalbody - "END" ":" "VCALENDAR" CRLF) - - The following is a simple example of an iCalendar object: - - BEGIN:VCALENDAR - VERSION:2.0 - PRODID:-//hacksw/handcal//NONSGML v1.0//EN - BEGIN:VEVENT - DTSTART:19970714T170000Z - DTEND:19970715T035959Z - SUMMARY:Bastille Day Party - END:VEVENT - END:VCALENDAR - - - - - - -Dawson & Stenerson Standards Track [Page 50] - -RFC 2445 iCalendar November 1998 - - -4.5 Property - - A property is the definition of an individual attribute describing a - calendar or a calendar component. A property takes the form defined - by the "contentline" notation defined in section 4.1.1. - - The following is an example of a property: - - DTSTART:19960415T133000Z - - This memo imposes no ordering of properties within an iCalendar - object. - - Property names, parameter names and enumerated parameter values are - case insensitive. For example, the property name "DUE" is the same as - "due" and "Due", DTSTART;TZID=US-Eastern:19980714T120000 is the same - as DtStart;TzID=US-Eastern:19980714T120000. - -4.6 Calendar Components - - The body of the iCalendar object consists of a sequence of calendar - properties and one or more calendar components. The calendar - properties are attributes that apply to the calendar as a whole. The - calendar components are collections of properties that express a - particular calendar semantic. For example, the calendar component can - specify an event, a to-do, a journal entry, time zone information, or - free/busy time information, or an alarm. - - The body of the iCalendar object is defined by the following - notation: - - icalbody = calprops component - - calprops = 2*( - - ; 'prodid' and 'version' are both REQUIRED, - ; but MUST NOT occur more than once - - prodid /version / - - ; 'calscale' and 'method' are optional, - ; but MUST NOT occur more than once - - calscale / - method / - - x-prop - - - - -Dawson & Stenerson Standards Track [Page 51] - -RFC 2445 iCalendar November 1998 - - - ) - - component = 1*(eventc / todoc / journalc / freebusyc / - / timezonec / iana-comp / x-comp) - - iana-comp = "BEGIN" ":" iana-token CRLF - - 1*contentline - - "END" ":" iana-token CRLF - - x-comp = "BEGIN" ":" x-name CRLF - - 1*contentline - - "END" ":" x-name CRLF - - An iCalendar object MUST include the "PRODID" and "VERSION" calendar - properties. In addition, it MUST include at least one calendar - component. Special forms of iCalendar objects are possible to publish - just busy time (i.e., only a "VFREEBUSY" calendar component) or time - zone (i.e., only a "VTIMEZONE" calendar component) information. In - addition, a complex iCalendar object is possible that is used to - capture a complete snapshot of the contents of a calendar (e.g., - composite of many different calendar components). More commonly, an - iCalendar object will consist of just a single "VEVENT", "VTODO" or - "VJOURNAL" calendar component. - -4.6.1 Event Component - - Component Name: "VEVENT" - - Purpose: Provide a grouping of component properties that describe an - event. - - Format Definition: A "VEVENT" calendar component is defined by the - following notation: - - eventc = "BEGIN" ":" "VEVENT" CRLF - eventprop *alarmc - "END" ":" "VEVENT" CRLF - - eventprop = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - class / created / description / dtstart / geo / - - - -Dawson & Stenerson Standards Track [Page 52] - -RFC 2445 iCalendar November 1998 - - - last-mod / location / organizer / priority / - dtstamp / seq / status / summary / transp / - uid / url / recurid / - - ; either 'dtend' or 'duration' may appear in - ; a 'eventprop', but 'dtend' and 'duration' - ; MUST NOT occur in the same 'eventprop' - - dtend / duration / - - ; the following are optional, - ; and MAY occur more than once - - attach / attendee / categories / comment / - contact / exdate / exrule / rstatus / related / - resources / rdate / rrule / x-prop - - ) - - Description: A "VEVENT" calendar component is a grouping of component - properties, and possibly including "VALARM" calendar components, that - represents a scheduled amount of time on a calendar. For example, it - can be an activity; such as a one-hour long, department meeting from - 8:00 AM to 9:00 AM, tomorrow. Generally, an event will take up time - on an individual calendar. Hence, the event will appear as an opaque - interval in a search for busy time. Alternately, the event can have - its Time Transparency set to "TRANSPARENT" in order to prevent - blocking of the event in searches for busy time. - - The "VEVENT" is also the calendar component used to specify an - anniversary or daily reminder within a calendar. These events have a - DATE value type for the "DTSTART" property instead of the default - data type of DATE-TIME. If such a "VEVENT" has a "DTEND" property, it - MUST be specified as a DATE value also. The anniversary type of - "VEVENT" can span more than one date (i.e, "DTEND" property value is - set to a calendar date after the "DTSTART" property value). - - The "DTSTART" property for a "VEVENT" specifies the inclusive start - of the event. For recurring events, it also specifies the very first - instance in the recurrence set. The "DTEND" property for a "VEVENT" - calendar component specifies the non-inclusive end of the event. For - cases where a "VEVENT" calendar component specifies a "DTSTART" - property with a DATE data type but no "DTEND" property, the events - non-inclusive end is the end of the calendar date specified by the - "DTSTART" property. For cases where a "VEVENT" calendar component - specifies a "DTSTART" property with a DATE-TIME data type but no - "DTEND" property, the event ends on the same calendar date and time - of day specified by the "DTSTART" property. - - - -Dawson & Stenerson Standards Track [Page 53] - -RFC 2445 iCalendar November 1998 - - - The "VEVENT" calendar component cannot be nested within another - calendar component. However, "VEVENT" calendar components can be - related to each other or to a "VTODO" or to a "VJOURNAL" calendar - component with the "RELATED-TO" property. - - Example: The following is an example of the "VEVENT" calendar - component used to represent a meeting that will also be opaque to - searches for busy time: - - BEGIN:VEVENT - UID:19970901T130000Z-123401@host.com - DTSTAMP:19970901T1300Z - DTSTART:19970903T163000Z - DTEND:19970903T190000Z - SUMMARY:Annual Employee Review - CLASS:PRIVATE - CATEGORIES:BUSINESS,HUMAN RESOURCES - END:VEVENT - - The following is an example of the "VEVENT" calendar component used - to represent a reminder that will not be opaque, but rather - transparent, to searches for busy time: - - BEGIN:VEVENT - UID:19970901T130000Z-123402@host.com - DTSTAMP:19970901T1300Z - DTSTART:19970401T163000Z - DTEND:19970402T010000Z - SUMMARY:Laurel is in sensitivity awareness class. - CLASS:PUBLIC - CATEGORIES:BUSINESS,HUMAN RESOURCES - TRANSP:TRANSPARENT - END:VEVENT - - The following is an example of the "VEVENT" calendar component used - to represent an anniversary that will occur annually. Since it takes - up no time, it will not appear as opaque in a search for busy time; - no matter what the value of the "TRANSP" property indicates: - - BEGIN:VEVENT - UID:19970901T130000Z-123403@host.com - DTSTAMP:19970901T1300Z - DTSTART:19971102 - SUMMARY:Our Blissful Anniversary - CLASS:CONFIDENTIAL - CATEGORIES:ANNIVERSARY,PERSONAL,SPECIAL OCCASION - RRULE:FREQ=YEARLY - END:VEVENT - - - -Dawson & Stenerson Standards Track [Page 54] - -RFC 2445 iCalendar November 1998 - - -4.6.2 To-do Component - - Component Name: VTODO - - Purpose: Provide a grouping of calendar properties that describe a - to-do. - - Formal Definition: A "VTODO" calendar component is defined by the - following notation: - - todoc = "BEGIN" ":" "VTODO" CRLF - todoprop *alarmc - "END" ":" "VTODO" CRLF - - todoprop = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - class / completed / created / description / dtstamp / - dtstart / geo / last-mod / location / organizer / - percent / priority / recurid / seq / status / - summary / uid / url / - - ; either 'due' or 'duration' may appear in - ; a 'todoprop', but 'due' and 'duration' - ; MUST NOT occur in the same 'todoprop' - - due / duration / - - ; the following are optional, - ; and MAY occur more than once - attach / attendee / categories / comment / contact / - exdate / exrule / rstatus / related / resources / - rdate / rrule / x-prop - - ) - - Description: A "VTODO" calendar component is a grouping of component - properties and possibly "VALARM" calendar components that represent - an action-item or assignment. For example, it can be used to - represent an item of work assigned to an individual; such as "turn in - travel expense today". - - The "VTODO" calendar component cannot be nested within another - calendar component. However, "VTODO" calendar components can be - related to each other or to a "VTODO" or to a "VJOURNAL" calendar - component with the "RELATED-TO" property. - - - -Dawson & Stenerson Standards Track [Page 55] - -RFC 2445 iCalendar November 1998 - - - A "VTODO" calendar component without the "DTSTART" and "DUE" (or - "DURATION") properties specifies a to-do that will be associated with - each successive calendar date, until it is completed. - - Example: The following is an example of a "VTODO" calendar component: - - BEGIN:VTODO - UID:19970901T130000Z-123404@host.com - DTSTAMP:19970901T1300Z - DTSTART:19970415T133000Z - DUE:19970416T045959Z - SUMMARY:1996 Income Tax Preparation - CLASS:CONFIDENTIAL - CATEGORIES:FAMILY,FINANCE - PRIORITY:1 - STATUS:NEEDS-ACTION - END:VTODO - -4.6.3 Journal Component - - Component Name: VJOURNAL - - Purpose: Provide a grouping of component properties that describe a - journal entry. - - Formal Definition: A "VJOURNAL" calendar component is defined by the - following notation: - - journalc = "BEGIN" ":" "VJOURNAL" CRLF - jourprop - "END" ":" "VJOURNAL" CRLF - - jourprop = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - class / created / description / dtstart / dtstamp / - last-mod / organizer / recurid / seq / status / - summary / uid / url / - - ; the following are optional, - ; and MAY occur more than once - - attach / attendee / categories / comment / - contact / exdate / exrule / related / rdate / - rrule / rstatus / x-prop - - - - -Dawson & Stenerson Standards Track [Page 56] - -RFC 2445 iCalendar November 1998 - - - ) - - Description: A "VJOURNAL" calendar component is a grouping of - component properties that represent one or more descriptive text - notes associated with a particular calendar date. The "DTSTART" - property is used to specify the calendar date that the journal entry - is associated with. Generally, it will have a DATE value data type, - but it can also be used to specify a DATE-TIME value data type. - Examples of a journal entry include a daily record of a legislative - body or a journal entry of individual telephone contacts for the day - or an ordered list of accomplishments for the day. The "VJOURNAL" - calendar component can also be used to associate a document with a - calendar date. - - The "VJOURNAL" calendar component does not take up time on a - calendar. Hence, it does not play a role in free or busy time - searches - - it is as though it has a time transparency value of - TRANSPARENT. It is transparent to any such searches. - - The "VJOURNAL" calendar component cannot be nested within another - calendar component. However, "VJOURNAL" calendar components can be - related to each other or to a "VEVENT" or to a "VTODO" calendar - component, with the "RELATED-TO" property. - - Example: The following is an example of the "VJOURNAL" calendar - component: - - BEGIN:VJOURNAL - UID:19970901T130000Z-123405@host.com - DTSTAMP:19970901T1300Z - DTSTART;VALUE=DATE:19970317 - SUMMARY:Staff meeting minutes - DESCRIPTION:1. Staff meeting: Participants include Joe\, Lisa - and Bob. Aurora project plans were reviewed. There is currently - no budget reserves for this project. Lisa will escalate to - management. Next meeting on Tuesday.\n - 2. Telephone Conference: ABC Corp. sales representative called - to discuss new printer. Promised to get us a demo by Friday.\n - 3. Henry Miller (Handsoff Insurance): Car was totaled by tree. - Is looking into a loaner car. 654-2323 (tel). - END:VJOURNAL - - - - - - - - - - -Dawson & Stenerson Standards Track [Page 57] - -RFC 2445 iCalendar November 1998 - - -4.6.4 Free/Busy Component - - Component Name: VFREEBUSY - - Purpose: Provide a grouping of component properties that describe - either a request for free/busy time, describe a response to a request - for free/busy time or describe a published set of busy time. - - Formal Definition: A "VFREEBUSY" calendar component is defined by the - following notation: - - freebusyc = "BEGIN" ":" "VFREEBUSY" CRLF - fbprop - "END" ":" "VFREEBUSY" CRLF - - fbprop = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - contact / dtstart / dtend / duration / dtstamp / - organizer / uid / url / - - ; the following are optional, - ; and MAY occur more than once - - attendee / comment / freebusy / rstatus / x-prop - - ) - - Description: A "VFREEBUSY" calendar component is a grouping of - component properties that represents either a request for, a reply to - a request for free or busy time information or a published set of - busy time information. - - When used to request free/busy time information, the "ATTENDEE" - property specifies the calendar users whose free/busy time is being - requested; the "ORGANIZER" property specifies the calendar user who - is requesting the free/busy time; the "DTSTART" and "DTEND" - properties specify the window of time for which the free/busy time is - being requested; the "UID" and "DTSTAMP" properties are specified to - assist in proper sequencing of multiple free/busy time requests. - - When used to reply to a request for free/busy time, the "ATTENDEE" - property specifies the calendar user responding to the free/busy time - request; the "ORGANIZER" property specifies the calendar user that - originally requested the free/busy time; the "FREEBUSY" property - specifies the free/busy time information (if it exists); and the - - - -Dawson & Stenerson Standards Track [Page 58] - -RFC 2445 iCalendar November 1998 - - - "UID" and "DTSTAMP" properties are specified to assist in proper - sequencing of multiple free/busy time replies. - - When used to publish busy time, the "ORGANIZER" property specifies - the calendar user associated with the published busy time; the - "DTSTART" and "DTEND" properties specify an inclusive time window - that surrounds the busy time information; the "FREEBUSY" property - specifies the published busy time information; and the "DTSTAMP" - property specifies the date/time that iCalendar object was created. - - The "VFREEBUSY" calendar component cannot be nested within another - calendar component. Multiple "VFREEBUSY" calendar components can be - specified within an iCalendar object. This permits the grouping of - Free/Busy information into logical collections, such as monthly - groups of busy time information. - - The "VFREEBUSY" calendar component is intended for use in iCalendar - object methods involving requests for free time, requests for busy - time, requests for both free and busy, and the associated replies. - - Free/Busy information is represented with the "FREEBUSY" property. - This property provides a terse representation of time periods. One or - more "FREEBUSY" properties can be specified in the "VFREEBUSY" - calendar component. - - When present in a "VFREEBUSY" calendar component, the "DTSTART" and - "DTEND" properties SHOULD be specified prior to any "FREEBUSY" - properties. In a free time request, these properties can be used in - combination with the "DURATION" property to represent a request for a - duration of free time within a specified window of time. - - The recurrence properties ("RRULE", "EXRULE", "RDATE", "EXDATE") are - not permitted within a "VFREEBUSY" calendar component. Any recurring - events are resolved into their individual busy time periods using the - "FREEBUSY" property. - - Example: The following is an example of a "VFREEBUSY" calendar - component used to request free or busy time information: - - BEGIN:VFREEBUSY - ORGANIZER:MAILTO:jane_doe@host1.com - ATTENDEE:MAILTO:john_public@host2.com - DTSTART:19971015T050000Z - DTEND:19971016T050000Z - DTSTAMP:19970901T083000Z - END:VFREEBUSY - - - - - -Dawson & Stenerson Standards Track [Page 59] - -RFC 2445 iCalendar November 1998 - - - The following is an example of a "VFREEBUSY" calendar component used - to reply to the request with busy time information: - - BEGIN:VFREEBUSY - ORGANIZER:MAILTO:jane_doe@host1.com - ATTENDEE:MAILTO:john_public@host2.com - DTSTAMP:19970901T100000Z - FREEBUSY;VALUE=PERIOD:19971015T050000Z/PT8H30M, - 19971015T160000Z/PT5H30M,19971015T223000Z/PT6H30M - URL:http://host2.com/pub/busy/jpublic-01.ifb - COMMENT:This iCalendar file contains busy time information for - the next three months. - END:VFREEBUSY - - The following is an example of a "VFREEBUSY" calendar component used - to publish busy time information. - - BEGIN:VFREEBUSY - ORGANIZER:jsmith@host.com - DTSTART:19980313T141711Z - DTEND:19980410T141711Z - FREEBUSY:19980314T233000Z/19980315T003000Z - FREEBUSY:19980316T153000Z/19980316T163000Z - FREEBUSY:19980318T030000Z/19980318T040000Z - URL:http://www.host.com/calendar/busytime/jsmith.ifb - END:VFREEBUSY - -4.6.5 Time Zone Component - - Component Name: VTIMEZONE - - Purpose: Provide a grouping of component properties that defines a - time zone. - - Formal Definition: A "VTIMEZONE" calendar component is defined by the - following notation: - - timezonec = "BEGIN" ":" "VTIMEZONE" CRLF - - 2*( - - ; 'tzid' is required, but MUST NOT occur more - ; than once - - tzid / - - ; 'last-mod' and 'tzurl' are optional, - but MUST NOT occur more than once - - - -Dawson & Stenerson Standards Track [Page 60] - -RFC 2445 iCalendar November 1998 - - - last-mod / tzurl / - - ; one of 'standardc' or 'daylightc' MUST occur - ..; and each MAY occur more than once. - - standardc / daylightc / - - ; the following is optional, - ; and MAY occur more than once - - x-prop - - ) - - "END" ":" "VTIMEZONE" CRLF - - standardc = "BEGIN" ":" "STANDARD" CRLF - - tzprop - - "END" ":" "STANDARD" CRLF - - daylightc = "BEGIN" ":" "DAYLIGHT" CRLF - - tzprop - - "END" ":" "DAYLIGHT" CRLF - - tzprop = 3*( - - ; the following are each REQUIRED, - ; but MUST NOT occur more than once - - dtstart / tzoffsetto / tzoffsetfrom / - - ; the following are optional, - ; and MAY occur more than once - - comment / rdate / rrule / tzname / x-prop - - ) - - Description: A time zone is unambiguously defined by the set of time - measurement rules determined by the governing body for a given - geographic area. These rules describe at a minimum the base offset - from UTC for the time zone, often referred to as the Standard Time - offset. Many locations adjust their Standard Time forward or backward - by one hour, in order to accommodate seasonal changes in number of - - - -Dawson & Stenerson Standards Track [Page 61] - -RFC 2445 iCalendar November 1998 - - - daylight hours, often referred to as Daylight Saving Time. Some - locations adjust their time by a fraction of an hour. Standard Time - is also known as Winter Time. Daylight Saving Time is also known as - Advanced Time, Summer Time, or Legal Time in certain countries. The - following table shows the changes in time zone rules in effect for - New York City starting from 1967. Each line represents a description - or rule for a particular observance. - - Effective Observance Rule - - Date (Date/Time) Offset Abbreviation - - 1967-* last Sun in Oct, 02:00 -0500 EST - - 1967-1973 last Sun in Apr, 02:00 -0400 EDT - - 1974-1974 Jan 6, 02:00 -0400 EDT - - 1975-1975 Feb 23, 02:00 -0400 EDT - - 1976-1986 last Sun in Apr, 02:00 -0400 EDT - - 1987-* first Sun in Apr, 02:00 -0400 EDT - - Note: The specification of a global time zone registry is not - addressed by this document and is left for future study. - However, implementers may find the Olson time zone database [TZ] - a useful reference. It is an informal, public-domain collection - of time zone information, which is currently being maintained by - volunteer Internet participants, and is used in several - operating systems. This database contains current and historical - time zone information for a wide variety of locations around the - globe; it provides a time zone identifier for every unique time - zone rule set in actual use since 1970, with historical data - going back to the introduction of standard time. - - Interoperability between two calendaring and scheduling applications, - especially for recurring events, to-dos or journal entries, is - dependent on the ability to capture and convey date and time - information in an unambiguous format. The specification of current - time zone information is integral to this behavior. - - If present, the "VTIMEZONE" calendar component defines the set of - Standard Time and Daylight Saving Time observances (or rules) for a - particular time zone for a given interval of time. The "VTIMEZONE" - calendar component cannot be nested within other calendar components. - Multiple "VTIMEZONE" calendar components can exist in an iCalendar - object. In this situation, each "VTIMEZONE" MUST represent a unique - - - -Dawson & Stenerson Standards Track [Page 62] - -RFC 2445 iCalendar November 1998 - - - time zone definition. This is necessary for some classes of events, - such as airline flights, that start in one time zone and end in - another. - - The "VTIMEZONE" calendar component MUST be present if the iCalendar - object contains an RRULE that generates dates on both sides of a time - zone shift (e.g. both in Standard Time and Daylight Saving Time) - unless the iCalendar object intends to convey a floating time (See - the section "4.1.10.11 Time" for proper interpretation of floating - time). It can be present if the iCalendar object does not contain - such a RRULE. In addition, if a RRULE is present, there MUST be valid - time zone information for all recurrence instances. - - The "VTIMEZONE" calendar component MUST include the "TZID" property - and at least one definition of a standard or daylight component. The - standard or daylight component MUST include the "DTSTART", - "TZOFFSETFROM" and "TZOFFSETTO" properties. - - An individual "VTIMEZONE" calendar component MUST be specified for - each unique "TZID" parameter value specified in the iCalendar object. - - Each "VTIMEZONE" calendar component consists of a collection of one - or more sub-components that describe the rule for a particular - observance (either a Standard Time or a Daylight Saving Time - observance). The "STANDARD" sub-component consists of a collection of - properties that describe Standard Time. The "DAYLIGHT" sub-component - consists of a collection of properties that describe Daylight Saving - Time. In general this collection of properties consists of: - - - the first onset date-time for the observance - - - the last onset date-time for the observance, if a last onset - is known. - - - the offset to be applied for the observance - - - a rule that describes the day and time when the observance - takes effect - - - an optional name for the observance - - For a given time zone, there may be multiple unique definitions of - the observances over a period of time. Each observance is described - using either a "STANDARD" or "DAYLIGHT" sub-component. The collection - of these sub-components is used to describe the time zone for a given - period of time. The offset to apply at any given time is found by - locating the observance that has the last onset date and time before - the time in question, and using the offset value from that - - - -Dawson & Stenerson Standards Track [Page 63] - -RFC 2445 iCalendar November 1998 - - - observance. - - The top-level properties in a "VTIMEZONE" calendar component are: - - The mandatory "TZID" property is a text value that uniquely - identifies the VTIMZONE calendar component within the scope of an - iCalendar object. - - The optional "LAST-MODIFIED" property is a UTC value that specifies - the date and time that this time zone definition was last updated. - - The optional "TZURL" property is url value that points to a published - VTIMEZONE definition. TZURL SHOULD refer to a resource that is - accessible by anyone who might need to interpret the object. This - SHOULD NOT normally be a file: URL or other URL that is not widely- - accessible. - - The collection of properties that are used to define the STANDARD and - DAYLIGHT sub-components include: - - The mandatory "DTSTART" property gives the effective onset date and - local time for the time zone sub-component definition. "DTSTART" in - this usage MUST be specified as a local DATE-TIME value. - - The mandatory "TZOFFSETFROM" property gives the UTC offset which is - in use when the onset of this time zone observance begins. - "TZOFFSETFROM" is combined with "DTSTART" to define the effective - onset for the time zone sub-component definition. For example, the - following represents the time at which the observance of Standard - Time took effect in Fall 1967 for New York City: - - DTSTART:19671029T020000 - - TZOFFSETFROM:-0400 - - The mandatory "TZOFFSETTO " property gives the UTC offset for the - time zone sub-component (Standard Time or Daylight Saving Time) when - this observance is in use. - - The optional "TZNAME" property is the customary name for the time - zone. It may be specified multiple times, to allow for specifying - multiple language variants of the time zone names. This could be used - for displaying dates. - - If specified, the onset for the observance defined by the time zone - sub-component is defined by either the "RRULE" or "RDATE" property. - If neither is specified, only one sub-component can be specified in - the "VTIMEZONE" calendar component and it is assumed that the single - - - -Dawson & Stenerson Standards Track [Page 64] - -RFC 2445 iCalendar November 1998 - - - observance specified is always in effect. - - The "RRULE" property defines the recurrence rule for the onset of the - observance defined by this time zone sub-component. Some specific - requirements for the usage of RRULE for this purpose include: - - - If observance is known to have an effective end date, the - "UNTIL" recurrence rule parameter MUST be used to specify the - last valid onset of this observance (i.e., the UNTIL date-time - will be equal to the last instance generated by the recurrence - pattern). It MUST be specified in UTC time. - - - The "DTSTART" and the "TZOFFSETTO" properties MUST be used - when generating the onset date-time values (instances) from the - RRULE. - - Alternatively, the "RDATE" property can be used to define the onset - of the observance by giving the individual onset date and times. - "RDATE" in this usage MUST be specified as a local DATE-TIME value in - UTC time. - - The optional "COMMENT" property is also allowed for descriptive - explanatory text. - - Example: The following are examples of the "VTIMEZONE" calendar - component: - - This is an example showing time zone information for the Eastern - United States using "RDATE" property. Note that this is only suitable - for a recurring event that starts on or later than April 6, 1997 at - 03:00:00 EDT (i.e., the earliest effective transition date and time) - and ends no later than April 7, 1998 02:00:00 EST (i.e., latest valid - date and time for EST in this scenario). For example, this can be - used for a recurring event that occurs every Friday, 8am-9:00 AM, - starting June 1, 1997, ending December 31, 1997. - - BEGIN:VTIMEZONE - TZID:US-Eastern - LAST-MODIFIED:19870101T000000Z - BEGIN:STANDARD - DTSTART:19971026T020000 - RDATE:19971026T020000 - TZOFFSETFROM:-0400 - TZOFFSETTO:-0500 - TZNAME:EST - END:STANDARD - BEGIN:DAYLIGHT - DTSTART:19971026T020000 - - - -Dawson & Stenerson Standards Track [Page 65] - -RFC 2445 iCalendar November 1998 - - - RDATE:19970406T020000 - TZOFFSETFROM:-0500 - TZOFFSETTO:-0400 - TZNAME:EDT - END:DAYLIGHT - END:VTIMEZONE - - This is a simple example showing the current time zone rules for the - Eastern United States using a RRULE recurrence pattern. Note that - there is no effective end date to either of the Standard Time or - Daylight Time rules. This information would be valid for a recurring - event starting today and continuing indefinitely. - - BEGIN:VTIMEZONE - TZID:US-Eastern - LAST-MODIFIED:19870101T000000Z - TZURL:http://zones.stds_r_us.net/tz/US-Eastern - BEGIN:STANDARD - DTSTART:19671029T020000 - RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 - TZOFFSETFROM:-0400 - TZOFFSETTO:-0500 - TZNAME:EST - END:STANDARD - BEGIN:DAYLIGHT - DTSTART:19870405T020000 - RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4 - TZOFFSETFROM:-0500 - TZOFFSETTO:-0400 - TZNAME:EDT - END:DAYLIGHT - END:VTIMEZONE - - This is an example showing a fictitious set of rules for the Eastern - United States, where the Daylight Time rule has an effective end date - (i.e., after that date, Daylight Time is no longer observed). - - BEGIN:VTIMEZONE - TZID:US--Fictitious-Eastern - LAST-MODIFIED:19870101T000000Z - BEGIN:STANDARD - DTSTART:19671029T020000 - RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 - TZOFFSETFROM:-0400 - TZOFFSETTO:-0500 - TZNAME:EST - END:STANDARD - - - - -Dawson & Stenerson Standards Track [Page 66] - -RFC 2445 iCalendar November 1998 - - - BEGIN:DAYLIGHT - DTSTART:19870405T020000 - RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z - TZOFFSETFROM:-0500 - TZOFFSETTO:-0400 - TZNAME:EDT - END:DAYLIGHT - END:VTIMEZONE - - This is an example showing a fictitious set of rules for the Eastern - United States, where the first Daylight Time rule has an effective - end date. There is a second Daylight Time rule that picks up where - the other left off. - - BEGIN:VTIMEZONE - TZID:US--Fictitious-Eastern - LAST-MODIFIED:19870101T000000Z - BEGIN:STANDARD - DTSTART:19671029T020000 - RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10 - TZOFFSETFROM:-0400 - TZOFFSETTO:-0500 - TZNAME:EST - END:STANDARD - BEGIN:DAYLIGHT - DTSTART:19870405T020000 - RRULE:FREQ=YEARLY;BYDAY=1SU;BYMONTH=4;UNTIL=19980404T070000Z - TZOFFSETFROM:-0500 - TZOFFSETTO:-0400 - TZNAME:EDT - END:DAYLIGHT - BEGIN:DAYLIGHT - DTSTART:19990424T020000 - RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=4 - TZOFFSETFROM:-0500 - TZOFFSETTO:-0400 - TZNAME:EDT - END:DAYLIGHT - END:VTIMEZONE - -4.6.6 Alarm Component - - Component Name: VALARM - - Purpose: Provide a grouping of component properties that define an - alarm. - - - - - -Dawson & Stenerson Standards Track [Page 67] - -RFC 2445 iCalendar November 1998 - - - Formal Definition: A "VALARM" calendar component is defined by the - following notation: - - alarmc = "BEGIN" ":" "VALARM" CRLF - (audioprop / dispprop / emailprop / procprop) - "END" ":" "VALARM" CRLF - - audioprop = 2*( - - ; 'action' and 'trigger' are both REQUIRED, - ; but MUST NOT occur more than once - - action / trigger / - - ; 'duration' and 'repeat' are both optional, - ; and MUST NOT occur more than once each, - ; but if one occurs, so MUST the other - - duration / repeat / - - ; the following is optional, - ; but MUST NOT occur more than once - - attach / - - ; the following is optional, - ; and MAY occur more than once - - x-prop - - ) - - - - dispprop = 3*( - - ; the following are all REQUIRED, - ; but MUST NOT occur more than once - - action / description / trigger / - - ; 'duration' and 'repeat' are both optional, - ; and MUST NOT occur more than once each, - ; but if one occurs, so MUST the other - - duration / repeat / - - ; the following is optional, - - - -Dawson & Stenerson Standards Track [Page 68] - -RFC 2445 iCalendar November 1998 - - - ; and MAY occur more than once - - *x-prop - - ) - - - - emailprop = 5*( - - ; the following are all REQUIRED, - ; but MUST NOT occur more than once - - action / description / trigger / summary - - ; the following is REQUIRED, - ; and MAY occur more than once - - attendee / - - ; 'duration' and 'repeat' are both optional, - ; and MUST NOT occur more than once each, - ; but if one occurs, so MUST the other - - duration / repeat / - - ; the following are optional, - ; and MAY occur more than once - - attach / x-prop - - ) - - - - procprop = 3*( - - ; the following are all REQUIRED, - ; but MUST NOT occur more than once - - action / attach / trigger / - - ; 'duration' and 'repeat' are both optional, - ; and MUST NOT occur more than once each, - ; but if one occurs, so MUST the other - - duration / repeat / - - - - -Dawson & Stenerson Standards Track [Page 69] - -RFC 2445 iCalendar November 1998 - - - ; 'description' is optional, - ; and MUST NOT occur more than once - - description / - - ; the following is optional, - ; and MAY occur more than once - - x-prop - - ) - - Description: A "VALARM" calendar component is a grouping of component - properties that is a reminder or alarm for an event or a to-do. For - example, it may be used to define a reminder for a pending event or - an overdue to-do. - - The "VALARM" calendar component MUST include the "ACTION" and - "TRIGGER" properties. The "ACTION" property further constrains the - "VALARM" calendar component in the following ways: - - When the action is "AUDIO", the alarm can also include one and only - one "ATTACH" property, which MUST point to a sound resource, which is - rendered when the alarm is triggered. - - When the action is "DISPLAY", the alarm MUST also include a - "DESCRIPTION" property, which contains the text to be displayed when - the alarm is triggered. - - When the action is "EMAIL", the alarm MUST include a "DESCRIPTION" - property, which contains the text to be used as the message body, a - "SUMMARY" property, which contains the text to be used as the message - subject, and one or more "ATTENDEE" properties, which contain the - email address of attendees to receive the message. It can also - include one or more "ATTACH" properties, which are intended to be - sent as message attachments. When the alarm is triggered, the email - message is sent. - - When the action is "PROCEDURE", the alarm MUST include one and only - one "ATTACH" property, which MUST point to a procedure resource, - which is invoked when the alarm is triggered. - - The "VALARM" calendar component MUST only appear within either a - "VEVENT" or "VTODO" calendar component. "VALARM" calendar components - cannot be nested. Multiple mutually independent "VALARM" calendar - components can be specified for a single "VEVENT" or "VTODO" calendar - component. - - - - -Dawson & Stenerson Standards Track [Page 70] - -RFC 2445 iCalendar November 1998 - - - The "TRIGGER" property specifies when the alarm will be triggered. - The "TRIGGER" property specifies a duration prior to the start of an - event or a to-do. The "TRIGGER" edge may be explicitly set to be - relative to the "START" or "END" of the event or to-do with the - "RELATED" parameter of the "TRIGGER" property. The "TRIGGER" property - value type can alternatively be set to an absolute calendar date and - time of day value. - - In an alarm set to trigger on the "START" of an event or to-do, the - "DTSTART" property MUST be present in the associated event or to-do. - In an alarm in a "VEVENT" calendar component set to trigger on the - "END" of the event, either the "DTEND" property MUST be present, or - the "DTSTART" and "DURATION" properties MUST both be present. In an - alarm in a "VTODO" calendar component set to trigger on the "END" of - the to-do, either the "DUE" property MUST be present, or the - "DTSTART" and "DURATION" properties MUST both be present. - - The alarm can be defined such that it triggers repeatedly. A - definition of an alarm with a repeating trigger MUST include both the - "DURATION" and "REPEAT" properties. The "DURATION" property specifies - the delay period, after which the alarm will repeat. The "REPEAT" - property specifies the number of additional repetitions that the - alarm will triggered. This repitition count is in addition to the - initial triggering of the alarm. Both of these properties MUST be - present in order to specify a repeating alarm. If one of these two - properties is absent, then the alarm will not repeat beyond the - initial trigger. - - The "ACTION" property is used within the "VALARM" calendar component - to specify the type of action invoked when the alarm is triggered. - The "VALARM" properties provide enough information for a specific - action to be invoked. It is typically the responsibility of a - "Calendar User Agent" (CUA) to deliver the alarm in the specified - fashion. An "ACTION" property value of AUDIO specifies an alarm that - causes a sound to be played to alert the user; DISPLAY specifies an - alarm that causes a text message to be displayed to the user; EMAIL - specifies an alarm that causes an electronic email message to be - delivered to one or more email addresses; and PROCEDURE specifies an - alarm that causes a procedure to be executed. The "ACTION" property - MUST specify one and only one of these values. - - In an AUDIO alarm, if the optional "ATTACH" property is included, it - MUST specify an audio sound resource. The intention is that the sound - will be played as the alarm effect. If an "ATTACH" property is - specified that does not refer to a sound resource, or if the - specified sound resource cannot be rendered (because its format is - unsupported, or because it cannot be retrieved), then the CUA or - other entity responsible for playing the sound may choose a fallback - - - -Dawson & Stenerson Standards Track [Page 71] - -RFC 2445 iCalendar November 1998 - - - action, such as playing a built-in default sound, or playing no sound - at all. - - In a DISPLAY alarm, the intended alarm effect is for the text value - of the "DESCRIPTION" property to be displayed to the user. - - In an EMAIL alarm, the intended alarm effect is for an email message - to be composed and delivered to all the addresses specified by the - "ATTENDEE" properties in the "VALARM" calendar component. The - "DESCRIPTION" property of the "VALARM" calendar component MUST be - used as the body text of the message, and the "SUMMARY" property MUST - be used as the subject text. Any "ATTACH" properties in the "VALARM" - calendar component SHOULD be sent as attachments to the message. - - In a PROCEDURE alarm, the "ATTACH" property in the "VALARM" calendar - component MUST specify a procedure or program that is intended to be - invoked as the alarm effect. If the procedure or program is in a - format that cannot be rendered, then no procedure alarm will be - invoked. If the "DESCRIPTION" property is present, its value - specifies the argument string to be passed to the procedure or - program. "Calendar User Agents" that receive an iCalendar object with - this category of alarm, can disable or allow the "Calendar User" to - disable, or otherwise ignore this type of alarm. While a very useful - alarm capability, the PROCEDURE type of alarm SHOULD be treated by - the "Calendar User Agent" as a potential security risk. - - Example: The following example is for a "VALARM" calendar component - that specifies an audio alarm that will sound at a precise time and - repeat 4 more times at 15 minute intervals: - - BEGIN:VALARM - TRIGGER;VALUE=DATE-TIME:19970317T133000Z - REPEAT:4 - DURATION:PT15M - ACTION:AUDIO - ATTACH;FMTTYPE=audio/basic:ftp://host.com/pub/sounds/bell-01.aud - END:VALARM - - The following example is for a "VALARM" calendar component that - specifies a display alarm that will trigger 30 minutes before the - scheduled start of the event or the due date/time of the to-do it is - associated with and will repeat 2 more times at 15 minute intervals: - - BEGIN:VALARM - TRIGGER:-PT30M - REPEAT:2 - DURATION:PT15M - ACTION:DISPLAY - - - -Dawson & Stenerson Standards Track [Page 72] - -RFC 2445 iCalendar November 1998 - - - DESCRIPTION:Breakfast meeting with executive\n - team at 8:30 AM EST. - END:VALARM - - The following example is for a "VALARM" calendar component that - specifies an email alarm that will trigger 2 days before the - scheduled due date/time of a to-do it is associated with. It does not - repeat. The email has a subject, body and attachment link. - - BEGIN:VALARM - TRIGGER:-P2D - ACTION:EMAIL - ATTENDEE:MAILTO:john_doe@host.com - SUMMARY:*** REMINDER: SEND AGENDA FOR WEEKLY STAFF MEETING *** - DESCRIPTION:A draft agenda needs to be sent out to the attendees - to the weekly managers meeting (MGR-LIST). Attached is a - pointer the document template for the agenda file. - ATTACH;FMTTYPE=application/binary:http://host.com/templates/agen - da.doc - END:VALARM - - The following example is for a "VALARM" calendar component that - specifies a procedural alarm that will trigger at a precise date/time - and will repeat 23 more times at one hour intervals. The alarm will - invoke a procedure file. - - BEGIN:VALARM - TRIGGER;VALUE=DATE-TIME:19980101T050000Z - REPEAT:23 - DURATION:PT1H - ACTION:PROCEDURE - ATTACH;FMTTYPE=application/binary:ftp://host.com/novo- - procs/felizano.exe - END:VALARM - -4.7 Calendar Properties - - The Calendar Properties are attributes that apply to the iCalendar - object, as a whole. These properties do not appear within a calendar - component. They SHOULD be specified after the "BEGIN:VCALENDAR" - property and prior to any calendar component. - -4.7.1 Calendar Scale - - Property Name: CALSCALE - - Purpose: This property defines the calendar scale used for the - calendar information specified in the iCalendar object. - - - -Dawson & Stenerson Standards Track [Page 73] - -RFC 2445 iCalendar November 1998 - - - Value Type: TEXT - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: Property can be specified in an iCalendar object. The - default value is "GREGORIAN". - - Description: This memo is based on the Gregorian calendar scale. The - Gregorian calendar scale is assumed if this property is not specified - in the iCalendar object. It is expected that other calendar scales - will be defined in other specifications or by future versions of this - memo. - - Format Definition: The property is defined by the following notation: - - calscale = "CALSCALE" calparam ":" calvalue CRLF - - calparam = *(";" xparam) - - calvalue = "GREGORIAN" / iana-token - - Example: The following is an example of this property: - - CALSCALE:GREGORIAN - -4.7.2 Method - - Property Name: METHOD - - Purpose: This property defines the iCalendar object method associated - with the calendar object. - - Value Type: TEXT - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: The property can be specified in an iCalendar object. - - Description: When used in a MIME message entity, the value of this - property MUST be the same as the Content-Type "method" parameter - value. This property can only appear once within the iCalendar - object. If either the "METHOD" property or the Content-Type "method" - parameter is specified, then the other MUST also be specified. - - No methods are defined by this specification. This is the subject of - other specifications, such as the iCalendar Transport-independent - - - -Dawson & Stenerson Standards Track [Page 74] - -RFC 2445 iCalendar November 1998 - - - Interoperability Protocol (iTIP) defined by [ITIP]. - - If this property is not present in the iCalendar object, then a - scheduling transaction MUST NOT be assumed. In such cases, the - iCalendar object is merely being used to transport a snapshot of some - calendar information; without the intention of conveying a scheduling - semantic. - - Format Definition: The property is defined by the following notation: - - method = "METHOD" metparam ":" metvalue CRLF - - metparam = *(";" xparam) - - metvalue = iana-token - - Example: The following is a hypothetical example of this property to - convey that the iCalendar object is a request for a meeting: - - METHOD:REQUEST - -4.7.3 Product Identifier - - Property Name: PRODID - - Purpose: This property specifies the identifier for the product that - created the iCalendar object. - - Value Type: TEXT - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: The property MUST be specified once in an iCalendar - object. - - Description: The vendor of the implementation SHOULD assure that this - is a globally unique identifier; using some technique such as an FPI - value, as defined in [ISO 9070]. - - This property SHOULD not be used to alter the interpretation of an - iCalendar object beyond the semantics specified in this memo. For - example, it is not to be used to further the understanding of non- - standard properties. - - Format Definition: The property is defined by the following notation: - - prodid = "PRODID" pidparam ":" pidvalue CRLF - - - -Dawson & Stenerson Standards Track [Page 75] - -RFC 2445 iCalendar November 1998 - - - pidparam = *(";" xparam) - - pidvalue = text - ;Any text that describes the product and version - ;and that is generally assured of being unique. - - Example: The following is an example of this property. It does not - imply that English is the default language. - - PRODID:-//ABC Corporation//NONSGML My Product//EN - -4.7.4 Version - - Property Name: VERSION - - Purpose: This property specifies the identifier corresponding to the - highest version number or the minimum and maximum range of the - iCalendar specification that is required in order to interpret the - iCalendar object. - - Value Type: TEXT - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: This property MUST be specified by an iCalendar object, - but MUST only be specified once. - - Description: A value of "2.0" corresponds to this memo. - - Format Definition: The property is defined by the following notation: - - version = "VERSION" verparam ":" vervalue CRLF - - verparam = *(";" xparam) - - vervalue = "2.0" ;This memo - / maxver - / (minver ";" maxver) - - minver = - ;Minimum iCalendar version needed to parse the iCalendar object - - maxver = - ;Maximum iCalendar version needed to parse the iCalendar object - - Example: The following is an example of this property: - - - - -Dawson & Stenerson Standards Track [Page 76] - -RFC 2445 iCalendar November 1998 - - - VERSION:2.0 - -4.8 Component Properties - - The following properties can appear within calendar components, as - specified by each component property definition. - -4.8.1 Descriptive Component Properties - - The following properties specify descriptive information about - calendar components. - -4.8.1.1 Attachment - - Property Name: ATTACH - - Purpose: The property provides the capability to associate a document - object with a calendar component. - - Value Type: The default value type for this property is URI. The - value type can also be set to BINARY to indicate inline binary - encoded content information. - - Property Parameters: Non-standard, inline encoding, format type and - value data type property parameters can be specified on this - property. - - Conformance: The property can be specified in a "VEVENT", "VTODO", - "VJOURNAL" or "VALARM" calendar components. - - Description: The property can be specified within "VEVENT", "VTODO", - "VJOURNAL", or "VALARM" calendar components. This property can be - specified multiple times within an iCalendar object. - - Format Definition: The property is defined by the following notation: - - attach = "ATTACH" attparam ":" uri CRLF - - attach =/ "ATTACH" attparam ";" "ENCODING" "=" "BASE64" - ";" "VALUE" "=" "BINARY" ":" binary - - attparam = *( - - ; the following is optional, - ; but MUST NOT occur more than once - - (";" fmttypeparam) / - - - - -Dawson & Stenerson Standards Track [Page 77] - -RFC 2445 iCalendar November 1998 - - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) - - Example: The following are examples of this property: - - ATTACH:CID:jsmith.part3.960817T083000.xyzMail@host1.com - - ATTACH;FMTTYPE=application/postscript:ftp://xyzCorp.com/pub/ - reports/r-960812.ps - -4.8.1.2 Categories - - Property Name: CATEGORIES - - Purpose: This property defines the categories for a calendar - component. - - Value Type: TEXT - - Property Parameters: Non-standard and language property parameters - can be specified on this property. - - Conformance: The property can be specified within "VEVENT", "VTODO" - or "VJOURNAL" calendar components. - - Description: This property is used to specify categories or subtypes - of the calendar component. The categories are useful in searching for - a calendar component of a particular type and category. Within the - "VEVENT", "VTODO" or "VJOURNAL" calendar components, more than one - category can be specified as a list of categories separated by the - COMMA character (US-ASCII decimal 44). - - Format Definition: The property is defined by the following notation: - - categories = "CATEGORIES" catparam ":" text *("," text) - CRLF - - catparam = *( - - ; the following is optional, - ; but MUST NOT occur more than once - - (";" languageparam ) / - - - - -Dawson & Stenerson Standards Track [Page 78] - -RFC 2445 iCalendar November 1998 - - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) - - Example: The following are examples of this property: - - CATEGORIES:APPOINTMENT,EDUCATION - - CATEGORIES:MEETING - -4.8.1.3 Classification - - Property Name: CLASS - - Purpose: This property defines the access classification for a - calendar component. - - Value Type: TEXT - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: The property can be specified once in a "VEVENT", - "VTODO" or "VJOURNAL" calendar components. - - Description: An access classification is only one component of the - general security system within a calendar application. It provides a - method of capturing the scope of the access the calendar owner - intends for information within an individual calendar entry. The - access classification of an individual iCalendar component is useful - when measured along with the other security components of a calendar - system (e.g., calendar user authentication, authorization, access - rights, access role, etc.). Hence, the semantics of the individual - access classifications cannot be completely defined by this memo - alone. Additionally, due to the "blind" nature of most exchange - processes using this memo, these access classifications cannot serve - as an enforcement statement for a system receiving an iCalendar - object. Rather, they provide a method for capturing the intention of - the calendar owner for the access to the calendar component. - - Format Definition: The property is defined by the following notation: - - class = "CLASS" classparam ":" classvalue CRLF - - classparam = *(";" xparam) - - - -Dawson & Stenerson Standards Track [Page 79] - -RFC 2445 iCalendar November 1998 - - - classvalue = "PUBLIC" / "PRIVATE" / "CONFIDENTIAL" / iana-token - / x-name - ;Default is PUBLIC - - Example: The following is an example of this property: - - CLASS:PUBLIC - -4.8.1.4 Comment - - Property Name: COMMENT - - Purpose: This property specifies non-processing information intended - to provide a comment to the calendar user. - - Value Type: TEXT - - Property Parameters: Non-standard, alternate text representation and - language property parameters can be specified on this property. - - Conformance: This property can be specified in "VEVENT", "VTODO", - "VJOURNAL", "VTIMEZONE" or "VFREEBUSY" calendar components. - - Description: The property can be specified multiple times. - - Format Definition: The property is defined by the following notation: - - comment = "COMMENT" commparam ":" text CRLF - - commparam = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - (";" altrepparam) / (";" languageparam) / - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) - - Example: The following is an example of this property: - - COMMENT:The meeting really needs to include both ourselves - and the customer. We can't hold this meeting without them. - As a matter of fact\, the venue for the meeting ought to be at - - - -Dawson & Stenerson Standards Track [Page 80] - -RFC 2445 iCalendar November 1998 - - - their site. - - John - - The data type for this property is TEXT. - -4.8.1.5 Description - - Property Name: DESCRIPTION - - Purpose: This property provides a more complete description of the - calendar component, than that provided by the "SUMMARY" property. - - Value Type: TEXT - - Property Parameters: Non-standard, alternate text representation and - language property parameters can be specified on this property. - - Conformance: The property can be specified in the "VEVENT", "VTODO", - "VJOURNAL" or "VALARM" calendar components. The property can be - specified multiple times only within a "VJOURNAL" calendar component. - - Description: This property is used in the "VEVENT" and "VTODO" to - capture lengthy textual decriptions associated with the activity. - - This property is used in the "VJOURNAL" calendar component to capture - one more textual journal entries. - - This property is used in the "VALARM" calendar component to capture - the display text for a DISPLAY category of alarm, to capture the body - text for an EMAIL category of alarm and to capture the argument - string for a PROCEDURE category of alarm. - - Format Definition: The property is defined by the following notation: - - description = "DESCRIPTION" descparam ":" text CRLF - - descparam = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - (";" altrepparam) / (";" languageparam) / - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) - - - -Dawson & Stenerson Standards Track [Page 81] - -RFC 2445 iCalendar November 1998 - - - Example: The following is an example of the property with formatted - line breaks in the property value: - - DESCRIPTION:Meeting to provide technical review for "Phoenix" - design.\n Happy Face Conference Room. Phoenix design team - MUST attend this meeting.\n RSVP to team leader. - - The following is an example of the property with folding of long - lines: - - DESCRIPTION:Last draft of the new novel is to be completed - for the editor's proof today. - -4.8.1.6 Geographic Position - - Property Name: GEO - - Purpose: This property specifies information related to the global - position for the activity specified by a calendar component. - - Value Type: FLOAT. The value MUST be two SEMICOLON separated FLOAT - values. - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: This property can be specified in "VEVENT" or "VTODO" - calendar components. - - Description: The property value specifies latitude and longitude, in - that order (i.e., "LAT LON" ordering). The longitude represents the - location east or west of the prime meridian as a positive or negative - real number, respectively. The longitude and latitude values MAY be - specified up to six decimal places, which will allow for accuracy to - within one meter of geographical position. Receiving applications - MUST accept values of this precision and MAY truncate values of - greater precision. - - Values for latitude and longitude shall be expressed as decimal - fractions of degrees. Whole degrees of latitude shall be represented - by a two-digit decimal number ranging from 0 through 90. Whole - degrees of longitude shall be represented by a decimal number ranging - from 0 through 180. When a decimal fraction of a degree is specified, - it shall be separated from the whole number of degrees by a decimal - point. - - - - - - -Dawson & Stenerson Standards Track [Page 82] - -RFC 2445 iCalendar November 1998 - - - Latitudes north of the equator shall be specified by a plus sign (+), - or by the absence of a minus sign (-), preceding the digits - designating degrees. Latitudes south of the Equator shall be - designated by a minus sign (-) preceding the digits designating - degrees. A point on the Equator shall be assigned to the Northern - Hemisphere. - - Longitudes east of the prime meridian shall be specified by a plus - sign (+), or by the absence of a minus sign (-), preceding the digits - designating degrees. Longitudes west of the meridian shall be - designated by minus sign (-) preceding the digits designating - degrees. A point on the prime meridian shall be assigned to the - Eastern Hemisphere. A point on the 180th meridian shall be assigned - to the Western Hemisphere. One exception to this last convention is - permitted. For the special condition of describing a band of latitude - around the earth, the East Bounding Coordinate data element shall be - assigned the value +180 (180) degrees. - - Any spatial address with a latitude of +90 (90) or -90 degrees will - specify the position at the North or South Pole, respectively. The - component for longitude may have any legal value. - - With the exception of the special condition described above, this - form is specified in Department of Commerce, 1986, Representation of - geographic point locations for information interchange (Federal - Information Processing Standard 70-1): Washington, Department of - Commerce, National Institute of Standards and Technology. - - The simple formula for converting degrees-minutes-seconds into - decimal degrees is: - - decimal = degrees + minutes/60 + seconds/3600. - - Format Definition: The property is defined by the following notation: - - geo = "GEO" geoparam ":" geovalue CRLF - - geoparam = *(";" xparam) - - geovalue = float ";" float - ;Latitude and Longitude components - - Example: The following is an example of this property: - - GEO:37.386013;-122.082932 - - - - - - -Dawson & Stenerson Standards Track [Page 83] - -RFC 2445 iCalendar November 1998 - - -4.8.1.7 Location - - Property Name: LOCATION - - Purpose: The property defines the intended venue for the activity - defined by a calendar component. - - Value Type: TEXT - - Property Parameters: Non-standard, alternate text representation and - language property parameters can be specified on this property. - - Conformance: This property can be specified in "VEVENT" or "VTODO" - calendar component. - - Description: Specific venues such as conference or meeting rooms may - be explicitly specified using this property. An alternate - representation may be specified that is a URI that points to - directory information with more structured specification of the - location. For example, the alternate representation may specify - either an LDAP URI pointing to an LDAP server entry or a CID URI - pointing to a MIME body part containing a vCard [RFC 2426] for the - location. - - Format Definition: The property is defined by the following notation: - - location = "LOCATION locparam ":" text CRLF - - locparam = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - (";" altrepparam) / (";" languageparam) / - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) - - Example: The following are some examples of this property: - - LOCATION:Conference Room - F123, Bldg. 002 - - LOCATION;ALTREP="http://xyzcorp.com/conf-rooms/f123.vcf": - Conference Room - F123, Bldg. 002 - - - -Dawson & Stenerson Standards Track [Page 84] - -RFC 2445 iCalendar November 1998 - - -4.8.1.8 Percent Complete - - Property Name: PERCENT-COMPLETE - - Purpose: This property is used by an assignee or delegatee of a to-do - to convey the percent completion of a to-do to the Organizer. - - Value Type: INTEGER - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: This property can be specified in a "VTODO" calendar - component. - - Description: The property value is a positive integer between zero - and one hundred. A value of "0" indicates the to-do has not yet been - started. A value of "100" indicates that the to-do has been - completed. Integer values in between indicate the percent partially - complete. - - When a to-do is assigned to multiple individuals, the property value - indicates the percent complete for that portion of the to-do assigned - to the assignee or delegatee. For example, if a to-do is assigned to - both individuals "A" and "B". A reply from "A" with a percent - complete of "70" indicates that "A" has completed 70% of the to-do - assigned to them. A reply from "B" with a percent complete of "50" - indicates "B" has completed 50% of the to-do assigned to them. - - Format Definition: The property is defined by the following notation: - - percent = "PERCENT-COMPLETE" pctparam ":" integer CRLF - - pctparam = *(";" xparam) - - Example: The following is an example of this property to show 39% - completion: - - PERCENT-COMPLETE:39 - -4.8.1.9 Priority - - Property Name: PRIORITY - - Purpose: The property defines the relative priority for a calendar - component. - - Value Type: INTEGER - - - -Dawson & Stenerson Standards Track [Page 85] - -RFC 2445 iCalendar November 1998 - - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: The property can be specified in a "VEVENT" or "VTODO" - calendar component. - - Description: The priority is specified as an integer in the range - zero to nine. A value of zero (US-ASCII decimal 48) specifies an - undefined priority. A value of one (US-ASCII decimal 49) is the - highest priority. A value of two (US-ASCII decimal 50) is the second - highest priority. Subsequent numbers specify a decreasing ordinal - priority. A value of nine (US-ASCII decimal 58) is the lowest - priority. - - A CUA with a three-level priority scheme of "HIGH", "MEDIUM" and - "LOW" is mapped into this property such that a property value in the - range of one (US-ASCII decimal 49) to four (US-ASCII decimal 52) - specifies "HIGH" priority. A value of five (US-ASCII decimal 53) is - the normal or "MEDIUM" priority. A value in the range of six (US- - ASCII decimal 54) to nine (US-ASCII decimal 58) is "LOW" priority. - - A CUA with a priority schema of "A1", "A2", "A3", "B1", "B2", ..., - "C3" is mapped into this property such that a property value of one - (US-ASCII decimal 49) specifies "A1", a property value of two (US- - ASCII decimal 50) specifies "A2", a property value of three (US-ASCII - decimal 51) specifies "A3", and so forth up to a property value of 9 - (US-ASCII decimal 58) specifies "C3". - - Other integer values are reserved for future use. - - Within a "VEVENT" calendar component, this property specifies a - priority for the event. This property may be useful when more than - one event is scheduled for a given time period. - - Within a "VTODO" calendar component, this property specified a - priority for the to-do. This property is useful in prioritizing - multiple action items for a given time period. - - Format Definition: The property is specified by the following - notation: - - priority = "PRIORITY" prioparam ":" privalue CRLF - ;Default is zero - - prioparam = *(";" xparam) - - privalue = integer ;Must be in the range [0..9] - ; All other values are reserved for future use - - - -Dawson & Stenerson Standards Track [Page 86] - -RFC 2445 iCalendar November 1998 - - - The following is an example of a property with the highest priority: - - PRIORITY:1 - - The following is an example of a property with a next highest - priority: - - PRIORITY:2 - - Example: The following is an example of a property with no priority. - This is equivalent to not specifying the "PRIORITY" property: - - PRIORITY:0 - -4.8.1.10 Resources - - Property Name: RESOURCES - - Purpose: This property defines the equipment or resources anticipated - for an activity specified by a calendar entity.. - - Value Type: TEXT - - Property Parameters: Non-standard, alternate text representation and - language property parameters can be specified on this property. - - Conformance: This property can be specified in "VEVENT" or "VTODO" - calendar component. - - Description: The property value is an arbitrary text. More than one - resource can be specified as a list of resources separated by the - COMMA character (US-ASCII decimal 44). - - Format Definition: The property is defined by the following notation: - - resources = "RESOURCES" resrcparam ":" text *("," text) CRLF - - resrcparam = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - (";" altrepparam) / (";" languageparam) / - - ; the following is optional, - ; and MAY occur more than once - - - - - -Dawson & Stenerson Standards Track [Page 87] - -RFC 2445 iCalendar November 1998 - - - (";" xparam) - - ) - - Example: The following is an example of this property: - - RESOURCES:EASEL,PROJECTOR,VCR - - RESOURCES;LANGUAGE=fr:1 raton-laveur - -4.8.1.11 Status - - Property Name: STATUS - - Purpose: This property defines the overall status or confirmation for - the calendar component. - - Value Type: TEXT - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: This property can be specified in "VEVENT", "VTODO" or - "VJOURNAL" calendar components. - - Description: In a group scheduled calendar component, the property is - used by the "Organizer" to provide a confirmation of the event to the - "Attendees". For example in a "VEVENT" calendar component, the - "Organizer" can indicate that a meeting is tentative, confirmed or - cancelled. In a "VTODO" calendar component, the "Organizer" can - indicate that an action item needs action, is completed, is in - process or being worked on, or has been cancelled. In a "VJOURNAL" - calendar component, the "Organizer" can indicate that a journal entry - is draft, final or has been cancelled or removed. - - Format Definition: The property is defined by the following notation: - - status = "STATUS" statparam] ":" statvalue CRLF - - statparam = *(";" xparam) - - statvalue = "TENTATIVE" ;Indicates event is - ;tentative. - / "CONFIRMED" ;Indicates event is - ;definite. - / "CANCELLED" ;Indicates event was - ;cancelled. - ;Status values for a "VEVENT" - - - -Dawson & Stenerson Standards Track [Page 88] - -RFC 2445 iCalendar November 1998 - - - statvalue =/ "NEEDS-ACTION" ;Indicates to-do needs action. - / "COMPLETED" ;Indicates to-do completed. - / "IN-PROCESS" ;Indicates to-do in process of - / "CANCELLED" ;Indicates to-do was cancelled. - ;Status values for "VTODO". - - statvalue =/ "DRAFT" ;Indicates journal is draft. - / "FINAL" ;Indicates journal is final. - / "CANCELLED" ;Indicates journal is removed. - ;Status values for "VJOURNAL". - - Example: The following is an example of this property for a "VEVENT" - calendar component: - - STATUS:TENTATIVE - - The following is an example of this property for a "VTODO" calendar - component: - - STATUS:NEEDS-ACTION - - The following is an example of this property for a "VJOURNAL" - calendar component: - - STATUS:DRAFT - -4.8.1.12 Summary - - Property Name: SUMMARY - - Purpose: This property defines a short summary or subject for the - calendar component. - - Value Type: TEXT - - Property Parameters: Non-standard, alternate text representation and - language property parameters can be specified on this property. - - Conformance: The property can be specified in "VEVENT", "VTODO", - "VJOURNAL" or "VALARM" calendar components. - - Description: This property is used in the "VEVENT", "VTODO" and - "VJOURNAL" calendar components to capture a short, one line summary - about the activity or journal entry. - - This property is used in the "VALARM" calendar component to capture - the subject of an EMAIL category of alarm. - - - - -Dawson & Stenerson Standards Track [Page 89] - -RFC 2445 iCalendar November 1998 - - - Format Definition: The property is defined by the following notation: - - summary = "SUMMARY" summparam ":" text CRLF - - summparam = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - (";" altrepparam) / (";" languageparam) / - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) - - Example: The following is an example of this property: - - SUMMARY:Department Party - -4.8.2 Date and Time Component Properties - - The following properties specify date and time related information in - calendar components. - -4.8.2.1 Date/Time Completed - - Property Name: COMPLETED - - Purpose: This property defines the date and time that a to-do was - actually completed. - - Value Type: DATE-TIME - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: The property can be specified in a "VTODO" calendar - component. - - Description: The date and time MUST be in a UTC format. - - Format Definition: The property is defined by the following notation: - - completed = "COMPLETED" compparam ":" date-time CRLF - - - - -Dawson & Stenerson Standards Track [Page 90] - -RFC 2445 iCalendar November 1998 - - - compparam = *(";" xparam) - - Example: The following is an example of this property: - - COMPLETED:19960401T235959Z - -4.8.2.2 Date/Time End - - Property Name: DTEND - - Purpose: This property specifies the date and time that a calendar - component ends. - - Value Type: The default value type is DATE-TIME. The value type can - be set to a DATE value type. - - Property Parameters: Non-standard, value data type, time zone - identifier property parameters can be specified on this property. - - Conformance: This property can be specified in "VEVENT" or - "VFREEBUSY" calendar components. - - Description: Within the "VEVENT" calendar component, this property - defines the date and time by which the event ends. The value MUST be - later in time than the value of the "DTSTART" property. - - Within the "VFREEBUSY" calendar component, this property defines the - end date and time for the free or busy time information. The time - MUST be specified in the UTC time format. The value MUST be later in - time than the value of the "DTSTART" property. - - Format Definition: The property is defined by the following notation: - - dtend = "DTEND" dtendparam":" dtendval CRLF - - dtendparam = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - (";" "VALUE" "=" ("DATE-TIME" / "DATE")) / - (";" tzidparam) / - - ; the following is optional, - ; and MAY occur more than once - - - - - - -Dawson & Stenerson Standards Track [Page 91] - -RFC 2445 iCalendar November 1998 - - - (";" xparam) - - ) - - - - dtendval = date-time / date - ;Value MUST match value type - - Example: The following is an example of this property: - - DTEND:19960401T235959Z - - DTEND;VALUE=DATE:19980704 - -4.8.2.3 Date/Time Due - - Property Name: DUE - - Purpose: This property defines the date and time that a to-do is - expected to be completed. - - Value Type: The default value type is DATE-TIME. The value type can - be set to a DATE value type. - - Property Parameters: Non-standard, value data type, time zone - identifier property parameters can be specified on this property. - - Conformance: The property can be specified once in a "VTODO" calendar - component. - - Description: The value MUST be a date/time equal to or after the - DTSTART value, if specified. - - Format Definition: The property is defined by the following notation: - - due = "DUE" dueparam":" dueval CRLF - - dueparam = *( - ; the following are optional, - ; but MUST NOT occur more than once - - (";" "VALUE" "=" ("DATE-TIME" / "DATE")) / - (";" tzidparam) / - - ; the following is optional, - ; and MAY occur more than once - - - - -Dawson & Stenerson Standards Track [Page 92] - -RFC 2445 iCalendar November 1998 - - - *(";" xparam) - - ) - - - - dueval = date-time / date - ;Value MUST match value type - - Example: The following is an example of this property: - - DUE:19980430T235959Z - -4.8.2.4 Date/Time Start - - Property Name: DTSTART - - Purpose: This property specifies when the calendar component begins. - - Value Type: The default value type is DATE-TIME. The time value MUST - be one of the forms defined for the DATE-TIME value type. The value - type can be set to a DATE value type. - - Property Parameters: Non-standard, value data type, time zone - identifier property parameters can be specified on this property. - - Conformance: This property can be specified in the "VEVENT", "VTODO", - "VFREEBUSY", or "VTIMEZONE" calendar components. - - Description: Within the "VEVENT" calendar component, this property - defines the start date and time for the event. The property is - REQUIRED in "VEVENT" calendar components. Events can have a start - date/time but no end date/time. In that case, the event does not take - up any time. - - Within the "VFREEBUSY" calendar component, this property defines the - start date and time for the free or busy time information. The time - MUST be specified in UTC time. - - Within the "VTIMEZONE" calendar component, this property defines the - effective start date and time for a time zone specification. This - property is REQUIRED within each STANDARD and DAYLIGHT part included - in "VTIMEZONE" calendar components and MUST be specified as a local - DATE-TIME without the "TZID" property parameter. - - Format Definition: The property is defined by the following notation: - - dtstart = "DTSTART" dtstparam ":" dtstval CRLF - - - -Dawson & Stenerson Standards Track [Page 93] - -RFC 2445 iCalendar November 1998 - - - dtstparam = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - (";" "VALUE" "=" ("DATE-TIME" / "DATE")) / - (";" tzidparam) / - - ; the following is optional, - ; and MAY occur more than once - - *(";" xparam) - - ) - - - - dtstval = date-time / date - ;Value MUST match value type - - Example: The following is an example of this property: - - DTSTART:19980118T073000Z - -4.8.2.5 Duration - - Property Name: DURATION - - Purpose: The property specifies a positive duration of time. - - Value Type: DURATION - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: The property can be specified in "VEVENT", "VTODO", - "VFREEBUSY" or "VALARM" calendar components. - - Description: In a "VEVENT" calendar component the property may be - used to specify a duration of the event, instead of an explicit end - date/time. In a "VTODO" calendar component the property may be used - to specify a duration for the to-do, instead of an explicit due - date/time. In a "VFREEBUSY" calendar component the property may be - used to specify the interval of free time being requested. In a - "VALARM" calendar component the property may be used to specify the - delay period prior to repeating an alarm. - - Format Definition: The property is defined by the following notation: - - - -Dawson & Stenerson Standards Track [Page 94] - -RFC 2445 iCalendar November 1998 - - - duration = "DURATION" durparam ":" dur-value CRLF - ;consisting of a positive duration of time. - - durparam = *(";" xparam) - - Example: The following is an example of this property that specifies - an interval of time of 1 hour and zero minutes and zero seconds: - - DURATION:PT1H0M0S - - The following is an example of this property that specifies an - interval of time of 15 minutes. - - DURATION:PT15M - -4.8.2.6 Free/Busy Time - - Property Name: FREEBUSY - - Purpose: The property defines one or more free or busy time - intervals. - - Value Type: PERIOD. The date and time values MUST be in an UTC time - format. - - Property Parameters: Non-standard or free/busy time type property - parameters can be specified on this property. - - Conformance: The property can be specified in a "VFREEBUSY" calendar - component. - - Property Parameter: "FBTYPE" and non-standard parameters can be - specified on this property. - - Description: These time periods can be specified as either a start - and end date-time or a start date-time and duration. The date and - time MUST be a UTC time format. - - "FREEBUSY" properties within the "VFREEBUSY" calendar component - SHOULD be sorted in ascending order, based on start time and then end - time, with the earliest periods first. - - The "FREEBUSY" property can specify more than one value, separated by - the COMMA character (US-ASCII decimal 44). In such cases, the - "FREEBUSY" property values SHOULD all be of the same "FBTYPE" - property parameter type (e.g., all values of a particular "FBTYPE" - listed together in a single property). - - - - -Dawson & Stenerson Standards Track [Page 95] - -RFC 2445 iCalendar November 1998 - - - Format Definition: The property is defined by the following notation: - - freebusy = "FREEBUSY" fbparam ":" fbvalue - CRLF - - fbparam = *( - ; the following is optional, - ; but MUST NOT occur more than once - - (";" fbtypeparam) / - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) - - fbvalue = period *["," period] - ;Time value MUST be in the UTC time format. - - Example: The following are some examples of this property: - - FREEBUSY;FBTYPE=BUSY-UNAVAILABLE:19970308T160000Z/PT8H30M - - FREEBUSY;FBTYPE=FREE:19970308T160000Z/PT3H,19970308T200000Z/PT1H - - FREEBUSY;FBTYPE=FREE:19970308T160000Z/PT3H,19970308T200000Z/PT1H, - 19970308T230000Z/19970309T000000Z - -4.8.2.7 Time Transparency - - Property Name: TRANSP - - Purpose: This property defines whether an event is transparent or not - to busy time searches. - - Value Type: TEXT - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: This property can be specified once in a "VEVENT" - calendar component. - - Description: Time Transparency is the characteristic of an event that - determines whether it appears to consume time on a calendar. Events - that consume actual time for the individual or resource associated - - - -Dawson & Stenerson Standards Track [Page 96] - -RFC 2445 iCalendar November 1998 - - - with the calendar SHOULD be recorded as OPAQUE, allowing them to be - detected by free-busy time searches. Other events, which do not take - up the individual's (or resource's) time SHOULD be recorded as - TRANSPARENT, making them invisible to free-busy time searches. - - Format Definition: The property is specified by the following - notation: - - transp = "TRANSP" tranparam ":" transvalue CRLF - - tranparam = *(";" xparam) - - transvalue = "OPAQUE" ;Blocks or opaque on busy time searches. - / "TRANSPARENT" ;Transparent on busy time searches. - ;Default value is OPAQUE - - Example: The following is an example of this property for an event - that is transparent or does not block on free/busy time searches: - - TRANSP:TRANSPARENT - - The following is an example of this property for an event that is - opaque or blocks on free/busy time searches: - - TRANSP:OPAQUE - -4.8.3 Time Zone Component Properties - - The following properties specify time zone information in calendar - components. - -4.8.3.1 Time Zone Identifier - - Property Name: TZID - - Purpose: This property specifies the text value that uniquely - identifies the "VTIMEZONE" calendar component. - - Value Type: TEXT - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: This property MUST be specified in a "VTIMEZONE" - calendar component. - - - - - - -Dawson & Stenerson Standards Track [Page 97] - -RFC 2445 iCalendar November 1998 - - - Description: This is the label by which a time zone calendar - component is referenced by any iCalendar properties whose data type - is either DATE-TIME or TIME and not intended to specify a UTC or a - "floating" time. The presence of the SOLIDUS character (US-ASCII - decimal 47) as a prefix, indicates that this TZID represents an - unique ID in a globally defined time zone registry (when such - registry is defined). - - Note: This document does not define a naming convention for time - zone identifiers. Implementers may want to use the naming - conventions defined in existing time zone specifications such as - the public-domain Olson database [TZ]. The specification of - globally unique time zone identifiers is not addressed by this - document and is left for future study. - - Format Definition: This property is defined by the following - notation: - - tzid = "TZID" tzidpropparam ":" [tzidprefix] text CRLF - - tzidpropparam = *(";" xparam) - - ;tzidprefix = "/" - ; Defined previously. Just listed here for reader convenience. - - Example: The following are examples of non-globally unique time zone - identifiers: - - TZID:US-Eastern - - TZID:California-Los_Angeles - - The following is an example of a fictitious globally unique time zone - identifier: - - TZID:/US-New_York-New_York - -4.8.3.2 Time Zone Name - - Property Name: TZNAME - - Purpose: This property specifies the customary designation for a time - zone description. - - Value Type: TEXT - - Property Parameters: Non-standard and language property parameters - can be specified on this property. - - - -Dawson & Stenerson Standards Track [Page 98] - -RFC 2445 iCalendar November 1998 - - - Conformance: This property can be specified in a "VTIMEZONE" calendar - component. - - Description: This property may be specified in multiple languages; in - order to provide for different language requirements. - - Format Definition: This property is defined by the following - notation: - - tzname = "TZNAME" tznparam ":" text CRLF - - tznparam = *( - - ; the following is optional, - ; but MUST NOT occur more than once - - (";" languageparam) / - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) - - Example: The following are example of this property: - - TZNAME:EST - - The following is an example of this property when two different - languages for the time zone name are specified: - - TZNAME;LANGUAGE=en:EST - TZNAME;LANGUAGE=fr-CA:HNE - -4.8.3.3 Time Zone Offset From - - Property Name: TZOFFSETFROM - - Purpose: This property specifies the offset which is in use prior to - this time zone observance. - - Value Type: UTC-OFFSET - - Property Parameters: Non-standard property parameters can be - specified on this property. - - - - - -Dawson & Stenerson Standards Track [Page 99] - -RFC 2445 iCalendar November 1998 - - - Conformance: This property MUST be specified in a "VTIMEZONE" - calendar component. - - Description: This property specifies the offset which is in use prior - to this time observance. It is used to calculate the absolute time at - which the transition to a given observance takes place. This property - MUST only be specified in a "VTIMEZONE" calendar component. A - "VTIMEZONE" calendar component MUST include this property. The - property value is a signed numeric indicating the number of hours and - possibly minutes from UTC. Positive numbers represent time zones east - of the prime meridian, or ahead of UTC. Negative numbers represent - time zones west of the prime meridian, or behind UTC. - - Format Definition: The property is defined by the following notation: - - tzoffsetfrom = "TZOFFSETFROM" frmparam ":" utc-offset - CRLF - - frmparam = *(";" xparam) - - Example: The following are examples of this property: - - TZOFFSETFROM:-0500 - - TZOFFSETFROM:+1345 - -4.8.3.4 Time Zone Offset To - - Property Name: TZOFFSETTO - - Purpose: This property specifies the offset which is in use in this - time zone observance. - - Value Type: UTC-OFFSET - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: This property MUST be specified in a "VTIMEZONE" - calendar component. - - Description: This property specifies the offset which is in use in - this time zone observance. It is used to calculate the absolute time - for the new observance. The property value is a signed numeric - indicating the number of hours and possibly minutes from UTC. - Positive numbers represent time zones east of the prime meridian, or - ahead of UTC. Negative numbers represent time zones west of the prime - meridian, or behind UTC. - - - -Dawson & Stenerson Standards Track [Page 100] - -RFC 2445 iCalendar November 1998 - - - Format Definition: The property is defined by the following notation: - - tzoffsetto = "TZOFFSETTO" toparam ":" utc-offset CRLF - - toparam = *(";" xparam) - - Example: The following are examples of this property: - - TZOFFSETTO:-0400 - - TZOFFSETTO:+1245 - -4.8.3.5 Time Zone URL - - Property Name: TZURL - - Purpose: The TZURL provides a means for a VTIMEZONE component to - point to a network location that can be used to retrieve an up-to- - date version of itself. - - Value Type: URI - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: This property can be specified in a "VTIMEZONE" calendar - component. - - Description: The TZURL provides a means for a VTIMEZONE component to - point to a network location that can be used to retrieve an up-to- - date version of itself. This provides a hook to handle changes - government bodies impose upon time zone definitions. Retrieval of - this resource results in an iCalendar object containing a single - VTIMEZONE component and a METHOD property set to PUBLISH. - - Format Definition: The property is defined by the following notation: - - tzurl = "TZURL" tzurlparam ":" uri CRLF - - tzurlparam = *(";" xparam) - - Example: The following is an example of this property: - - TZURL:http://timezones.r.us.net/tz/US-California-Los_Angeles - - - - - - - -Dawson & Stenerson Standards Track [Page 101] - -RFC 2445 iCalendar November 1998 - - -4.8.4 Relationship Component Properties - - The following properties specify relationship information in calendar - components. - -4.8.4.1 Attendee - - Property Name: ATTENDEE - - Purpose: The property defines an "Attendee" within a calendar - component. - - Value Type: CAL-ADDRESS - - Property Parameters: Non-standard, language, calendar user type, - group or list membership, participation role, participation status, - RSVP expectation, delegatee, delegator, sent by, common name or - directory entry reference property parameters can be specified on - this property. - - Conformance: This property MUST be specified in an iCalendar object - that specifies a group scheduled calendar entity. This property MUST - NOT be specified in an iCalendar object when publishing the calendar - information (e.g., NOT in an iCalendar object that specifies the - publication of a calendar user's busy time, event, to-do or journal). - This property is not specified in an iCalendar object that specifies - only a time zone definition or that defines calendar entities that - are not group scheduled entities, but are entities only on a single - user's calendar. - - Description: The property MUST only be specified within calendar - components to specify participants, non-participants and the chair of - a group scheduled calendar entity. The property is specified within - an "EMAIL" category of the "VALARM" calendar component to specify an - email address that is to receive the email type of iCalendar alarm. - - The property parameter CN is for the common or displayable name - associated with the calendar address; ROLE, for the intended role - that the attendee will have in the calendar component; PARTSTAT, for - the status of the attendee's participation; RSVP, for indicating - whether the favor of a reply is requested; CUTYPE, to indicate the - type of calendar user; MEMBER, to indicate the groups that the - attendee belongs to; DELEGATED-TO, to indicate the calendar users - that the original request was delegated to; and DELEGATED-FROM, to - indicate whom the request was delegated from; SENT-BY, to indicate - whom is acting on behalf of the ATTENDEE; and DIR, to indicate the - URI that points to the directory information corresponding to the - attendee. These property parameters can be specified on an "ATTENDEE" - - - -Dawson & Stenerson Standards Track [Page 102] - -RFC 2445 iCalendar November 1998 - - - property in either a "VEVENT", "VTODO" or "VJOURNAL" calendar - component. They MUST not be specified in an "ATTENDEE" property in a - "VFREEBUSY" or "VALARM" calendar component. If the LANGUAGE property - parameter is specified, the identified language applies to the CN - parameter. - - A recipient delegated a request MUST inherit the RSVP and ROLE values - from the attendee that delegated the request to them. - - Multiple attendees can be specified by including multiple "ATTENDEE" - properties within the calendar component. - - Format Definition: The property is defined by the following notation: - - attendee = "ATTENDEE" attparam ":" cal-address CRLF - - attparam = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - (";" cutypeparam) / (";"memberparam) / - (";" roleparam) / (";" partstatparam) / - (";" rsvpparam) / (";" deltoparam) / - (";" delfromparam) / (";" sentbyparam) / - (";"cnparam) / (";" dirparam) / - (";" languageparam) / - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) - - Example: The following are examples of this property's use for a to- - do: - - ORGANIZER:MAILTO:jsmith@host1.com - ATTENDEE;MEMBER="MAILTO:DEV-GROUP@host2.com": - MAILTO:joecool@host2.com - ATTENDEE;DELEGATED-FROM="MAILTO:immud@host3.com": - MAILTO:ildoit@host1.com - - The following is an example of this property used for specifying - multiple attendees to an event: - - - - - -Dawson & Stenerson Standards Track [Page 103] - -RFC 2445 iCalendar November 1998 - - - ORGANIZER:MAILTO:jsmith@host1.com - ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=TENTATIVE;CN=Henry Cabot - :MAILTO:hcabot@host2.com - ATTENDEE;ROLE=REQ-PARTICIPANT;DELEGATED-FROM="MAILTO:bob@host.com" - ;PARTSTAT=ACCEPTED;CN=Jane Doe:MAILTO:jdoe@host1.com - - The following is an example of this property with a URI to the - directory information associated with the attendee: - - ATTENDEE;CN=John Smith;DIR="ldap://host.com:6666/o=eDABC% - 20Industries,c=3DUS??(cn=3DBJim%20Dolittle)":MAILTO:jimdo@ - host1.com - - The following is an example of this property with "delegatee" and - "delegator" information for an event: - - ORGANIZER;CN=John Smith:MAILTO:jsmith@host.com - ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=TENTATIVE;DELEGATED-FROM= - "MAILTO:iamboss@host2.com";CN=Henry Cabot:MAILTO:hcabot@ - host2.com - ATTENDEE;ROLE=NON-PARTICIPANT;PARTSTAT=DELEGATED;DELEGATED-TO= - "MAILTO:hcabot@host2.com";CN=The Big Cheese:MAILTO:iamboss - @host2.com - ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Jane Doe - :MAILTO:jdoe@host1.com - - Example: The following is an example of this property's use when - another calendar user is acting on behalf of the "Attendee": - - ATTENDEE;SENT-BY=MAILTO:jan_doe@host1.com;CN=John Smith:MAILTO: - jsmith@host1.com - -4.8.4.2 Contact - - Property Name: CONTACT - - Purpose: The property is used to represent contact information or - alternately a reference to contact information associated with the - calendar component. - - Value Type: TEXT - - Property Parameters: Non-standard, alternate text representation and - language property parameters can be specified on this property. - - Conformance: The property can be specified in a "VEVENT", "VTODO", - "VJOURNAL" or "VFREEBUSY" calendar component. - - - - -Dawson & Stenerson Standards Track [Page 104] - -RFC 2445 iCalendar November 1998 - - - Description: The property value consists of textual contact - information. An alternative representation for the property value can - also be specified that refers to a URI pointing to an alternate form, - such as a vCard [RFC 2426], for the contact information. - - Format Definition: The property is defined by the following notation: - - contact = "CONTACT" contparam ":" text CRLF - - contparam = *( - ; the following are optional, - ; but MUST NOT occur more than once - - (";" altrepparam) / (";" languageparam) / - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) - - Example: The following is an example of this property referencing - textual contact information: - - CONTACT:Jim Dolittle\, ABC Industries\, +1-919-555-1234 - - The following is an example of this property with an alternate - representation of a LDAP URI to a directory entry containing the - contact information: - - CONTACT;ALTREP="ldap://host.com:6666/o=3DABC%20Industries\, - c=3DUS??(cn=3DBJim%20Dolittle)":Jim Dolittle\, ABC Industries\, - +1-919-555-1234 - - The following is an example of this property with an alternate - representation of a MIME body part containing the contact - information, such as a vCard [RFC 2426] embedded in a [MIME-DIR] - content-type: - - CONTACT;ALTREP="CID=":Jim - Dolittle\, ABC Industries\, +1-919-555-1234 - - The following is an example of this property referencing a network - resource, such as a vCard [RFC 2426] object containing the contact - information: - - - - - -Dawson & Stenerson Standards Track [Page 105] - -RFC 2445 iCalendar November 1998 - - - CONTACT;ALTREP="http://host.com/pdi/jdoe.vcf":Jim - Dolittle\, ABC Industries\, +1-919-555-1234 - -4.8.4.3 Organizer - - Property Name: ORGANIZER - - Purpose: The property defines the organizer for a calendar component. - - Value Type: CAL-ADDRESS - - Property Parameters: Non-standard, language, common name, directory - entry reference, sent by property parameters can be specified on this - property. - - Conformance: This property MUST be specified in an iCalendar object - that specifies a group scheduled calendar entity. This property MUST - be specified in an iCalendar object that specifies the publication of - a calendar user's busy time. This property MUST NOT be specified in - an iCalendar object that specifies only a time zone definition or - that defines calendar entities that are not group scheduled entities, - but are entities only on a single user's calendar. - - Description: The property is specified within the "VEVENT", "VTODO", - "VJOURNAL calendar components to specify the organizer of a group - scheduled calendar entity. The property is specified within the - "VFREEBUSY" calendar component to specify the calendar user - requesting the free or busy time. When publishing a "VFREEBUSY" - calendar component, the property is used to specify the calendar that - the published busy time came from. - - The property has the property parameters CN, for specifying the - common or display name associated with the "Organizer", DIR, for - specifying a pointer to the directory information associated with the - "Organizer", SENT-BY, for specifying another calendar user that is - acting on behalf of the "Organizer". The non-standard parameters may - also be specified on this property. If the LANGUAGE property - parameter is specified, the identified language applies to the CN - parameter value. - - Format Definition: The property is defined by the following notation: - - organizer = "ORGANIZER" orgparam ":" - cal-address CRLF - - orgparam = *( - - ; the following are optional, - - - -Dawson & Stenerson Standards Track [Page 106] - -RFC 2445 iCalendar November 1998 - - - ; but MUST NOT occur more than once - - (";" cnparam) / (";" dirparam) / (";" sentbyparam) / - (";" languageparam) / - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) - - Example: The following is an example of this property: - - ORGANIZER;CN=John Smith:MAILTO:jsmith@host1.com - - The following is an example of this property with a pointer to the - directory information associated with the organizer: - - ORGANIZER;CN=JohnSmith;DIR="ldap://host.com:6666/o=3DDC%20Associ - ates,c=3DUS??(cn=3DJohn%20Smith)":MAILTO:jsmith@host1.com - - The following is an example of this property used by another calendar - user who is acting on behalf of the organizer, with responses - intended to be sent back to the organizer, not the other calendar - user: - - ORGANIZER;SENT-BY="MAILTO:jane_doe@host.com": - MAILTO:jsmith@host1.com - -4.8.4.4 Recurrence ID - - Property Name: RECURRENCE-ID - - Purpose: This property is used in conjunction with the "UID" and - "SEQUENCE" property to identify a specific instance of a recurring - "VEVENT", "VTODO" or "VJOURNAL" calendar component. The property - value is the effective value of the "DTSTART" property of the - recurrence instance. - - Value Type: The default value type for this property is DATE-TIME. - The time format can be any of the valid forms defined for a DATE-TIME - value type. See DATE-TIME value type definition for specific - interpretations of the various forms. The value type can be set to - DATE. - - - - - - -Dawson & Stenerson Standards Track [Page 107] - -RFC 2445 iCalendar November 1998 - - - Property Parameters: Non-standard property, value data type, time - zone identifier and recurrence identifier range parameters can be - specified on this property. - - Conformance: This property can be specified in an iCalendar object - containing a recurring calendar component. - - Description: The full range of calendar components specified by a - recurrence set is referenced by referring to just the "UID" property - value corresponding to the calendar component. The "RECURRENCE-ID" - property allows the reference to an individual instance within the - recurrence set. - - If the value of the "DTSTART" property is a DATE type value, then the - value MUST be the calendar date for the recurrence instance. - - The date/time value is set to the time when the original recurrence - instance would occur; meaning that if the intent is to change a - Friday meeting to Thursday, the date/time is still set to the - original Friday meeting. - - The "RECURRENCE-ID" property is used in conjunction with the "UID" - and "SEQUENCE" property to identify a particular instance of a - recurring event, to-do or journal. For a given pair of "UID" and - "SEQUENCE" property values, the "RECURRENCE-ID" value for a - recurrence instance is fixed. When the definition of the recurrence - set for a calendar component changes, and hence the "SEQUENCE" - property value changes, the "RECURRENCE-ID" for a given recurrence - instance might also change.The "RANGE" parameter is used to specify - the effective range of recurrence instances from the instance - specified by the "RECURRENCE-ID" property value. The default value - for the range parameter is the single recurrence instance only. The - value can also be "THISANDPRIOR" to indicate a range defined by the - given recurrence instance and all prior instances or the value can be - "THISANDFUTURE" to indicate a range defined by the given recurrence - instance and all subsequent instances. - - Format Definition: The property is defined by the following notation: - - recurid = "RECURRENCE-ID" ridparam ":" ridval CRLF - - ridparam = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - (";" "VALUE" "=" ("DATE-TIME" / "DATE)) / - (";" tzidparam) / (";" rangeparam) / - - - -Dawson & Stenerson Standards Track [Page 108] - -RFC 2445 iCalendar November 1998 - - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) - - ridval = date-time / date - ;Value MUST match value type - - Example: The following are examples of this property: - - RECURRENCE-ID;VALUE=DATE:19960401 - - RECURRENCE-ID;RANGE=THISANDFUTURE:19960120T120000Z - -4.8.4.5 Related To - - Property Name: RELATED-TO - - Purpose: The property is used to represent a relationship or - reference between one calendar component and another. - - Value Type: TEXT - - Property Parameters: Non-standard and relationship type property - parameters can be specified on this property. - - Conformance: The property can be specified one or more times in the - "VEVENT", "VTODO" or "VJOURNAL" calendar components. - - Description: The property value consists of the persistent, globally - unique identifier of another calendar component. This value would be - represented in a calendar component by the "UID" property. - - By default, the property value points to another calendar component - that has a PARENT relationship to the referencing object. The - "RELTYPE" property parameter is used to either explicitly state the - default PARENT relationship type to the referenced calendar component - or to override the default PARENT relationship type and specify - either a CHILD or SIBLING relationship. The PARENT relationship - indicates that the calendar component is a subordinate of the - referenced calendar component. The CHILD relationship indicates that - the calendar component is a superior of the referenced calendar - component. The SIBLING relationship indicates that the calendar - component is a peer of the referenced calendar component. - - - - - -Dawson & Stenerson Standards Track [Page 109] - -RFC 2445 iCalendar November 1998 - - - Changes to a calendar component referenced by this property can have - an implicit impact on the related calendar component. For example, if - a group event changes its start or end date or time, then the - related, dependent events will need to have their start and end dates - changed in a corresponding way. Similarly, if a PARENT calendar - component is canceled or deleted, then there is an implied impact to - the related CHILD calendar components. This property is intended only - to provide information on the relationship of calendar components. It - is up to the target calendar system to maintain any property - implications of this relationship. - - Format Definition: The property is defined by the following notation: - - related = "RELATED-TO" [relparam] ":" text CRLF - - relparam = *( - - ; the following is optional, - ; but MUST NOT occur more than once - - (";" reltypeparam) / - - ; the following is optional, - ; and MAY occur more than once - - (";" xparm) - - ) - - The following is an example of this property: - - RELATED-TO: - - RELATED-TO:<19960401-080045-4000F192713-0052@host1.com> - -4.8.4.6 Uniform Resource Locator - - Property Name: URL - - Purpose: This property defines a Uniform Resource Locator (URL) - associated with the iCalendar object. - - Value Type: URI - - Property Parameters: Non-standard property parameters can be - specified on this property. - - - - - -Dawson & Stenerson Standards Track [Page 110] - -RFC 2445 iCalendar November 1998 - - - Conformance: This property can be specified once in the "VEVENT", - "VTODO", "VJOURNAL" or "VFREEBUSY" calendar components. - - Description: This property may be used in a calendar component to - convey a location where a more dynamic rendition of the calendar - information associated with the calendar component can be found. This - memo does not attempt to standardize the form of the URI, nor the - format of the resource pointed to by the property value. If the URL - property and Content-Location MIME header are both specified, they - MUST point to the same resource. - - Format Definition: The property is defined by the following notation: - - url = "URL" urlparam ":" uri CRLF - - urlparam = *(";" xparam) - - Example: The following is an example of this property: - - URL:http://abc.com/pub/calendars/jsmith/mytime.ics - -4.8.4.7 Unique Identifier - - Property Name: UID - - Purpose: This property defines the persistent, globally unique - identifier for the calendar component. - - Value Type: TEXT - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: The property MUST be specified in the "VEVENT", "VTODO", - "VJOURNAL" or "VFREEBUSY" calendar components. - - Description: The UID itself MUST be a globally unique identifier. The - generator of the identifier MUST guarantee that the identifier is - unique. There are several algorithms that can be used to accomplish - this. The identifier is RECOMMENDED to be the identical syntax to the - [RFC 822] addr-spec. A good method to assure uniqueness is to put the - domain name or a domain literal IP address of the host on which the - identifier was created on the right hand side of the "@", and on the - left hand side, put a combination of the current calendar date and - time of day (i.e., formatted in as a DATE-TIME value) along with some - other currently unique (perhaps sequential) identifier available on - the system (for example, a process id number). Using a date/time - value on the left hand side and a domain name or domain literal on - - - -Dawson & Stenerson Standards Track [Page 111] - -RFC 2445 iCalendar November 1998 - - - the right hand side makes it possible to guarantee uniqueness since - no two hosts should be using the same domain name or IP address at - the same time. Though other algorithms will work, it is RECOMMENDED - that the right hand side contain some domain identifier (either of - the host itself or otherwise) such that the generator of the message - identifier can guarantee the uniqueness of the left hand side within - the scope of that domain. - - This is the method for correlating scheduling messages with the - referenced "VEVENT", "VTODO", or "VJOURNAL" calendar component. - - The full range of calendar components specified by a recurrence set - is referenced by referring to just the "UID" property value - corresponding to the calendar component. The "RECURRENCE-ID" property - allows the reference to an individual instance within the recurrence - set. - - This property is an important method for group scheduling - applications to match requests with later replies, modifications or - deletion requests. Calendaring and scheduling applications MUST - generate this property in "VEVENT", "VTODO" and "VJOURNAL" calendar - components to assure interoperability with other group scheduling - applications. This identifier is created by the calendar system that - generates an iCalendar object. - - Implementations MUST be able to receive and persist values of at - least 255 characters for this property. - - Format Definition: The property is defined by the following notation: - - uid = "UID" uidparam ":" text CRLF - - uidparam = *(";" xparam) - - Example: The following is an example of this property: - - UID:19960401T080045Z-4000F192713-0052@host1.com - -4.8.5 Recurrence Component Properties - - The following properties specify recurrence information in calendar - components. - -4.8.5.1 Exception Date/Times - - Property Name: EXDATE - - - - - -Dawson & Stenerson Standards Track [Page 112] - -RFC 2445 iCalendar November 1998 - - - Purpose: This property defines the list of date/time exceptions for a - recurring calendar component. - - Value Type: The default value type for this property is DATE-TIME. - The value type can be set to DATE. - - Property Parameters: Non-standard, value data type and time zone - identifier property parameters can be specified on this property. - - Conformance: This property can be specified in an iCalendar object - that includes a recurring calendar component. - - Description: The exception dates, if specified, are used in computing - the recurrence set. The recurrence set is the complete set of - recurrence instances for a calendar component. The recurrence set is - generated by considering the initial "DTSTART" property along with - the "RRULE", "RDATE", "EXDATE" and "EXRULE" properties contained - within the iCalendar object. The "DTSTART" property defines the first - instance in the recurrence set. Multiple instances of the "RRULE" and - "EXRULE" properties can also be specified to define more - sophisticated recurrence sets. The final recurrence set is generated - by gathering all of the start date-times generated by any of the - specified "RRULE" and "RDATE" properties, and then excluding any - start date and times which fall within the union of start date and - times generated by any specified "EXRULE" and "EXDATE" properties. - This implies that start date and times within exclusion related - properties (i.e., "EXDATE" and "EXRULE") take precedence over those - specified by inclusion properties (i.e., "RDATE" and "RRULE"). Where - duplicate instances are generated by the "RRULE" and "RDATE" - properties, only one recurrence is considered. Duplicate instances - are ignored. - - The "EXDATE" property can be used to exclude the value specified in - "DTSTART". However, in such cases the original "DTSTART" date MUST - still be maintained by the calendaring and scheduling system because - the original "DTSTART" value has inherent usage dependencies by other - properties such as the "RECURRENCE-ID". - - Format Definition: The property is defined by the following notation: - - exdate = "EXDATE" exdtparam ":" exdtval *("," exdtval) CRLF - - exdtparam = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - (";" "VALUE" "=" ("DATE-TIME" / "DATE")) / - - - -Dawson & Stenerson Standards Track [Page 113] - -RFC 2445 iCalendar November 1998 - - - (";" tzidparam) / - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) - - exdtval = date-time / date - ;Value MUST match value type - - Example: The following is an example of this property: - - EXDATE:19960402T010000Z,19960403T010000Z,19960404T010000Z - -4.8.5.2 Exception Rule - - Property Name: EXRULE - - Purpose: This property defines a rule or repeating pattern for an - exception to a recurrence set. - - Value Type: RECUR - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: This property can be specified in "VEVENT", "VTODO" or - "VJOURNAL" calendar components. - - Description: The exception rule, if specified, is used in computing - the recurrence set. The recurrence set is the complete set of - recurrence instances for a calendar component. The recurrence set is - generated by considering the initial "DTSTART" property along with - the "RRULE", "RDATE", "EXDATE" and "EXRULE" properties contained - within the iCalendar object. The "DTSTART" defines the first instance - in the recurrence set. Multiple instances of the "RRULE" and "EXRULE" - properties can also be specified to define more sophisticated - recurrence sets. The final recurrence set is generated by gathering - all of the start date-times generated by any of the specified "RRULE" - and "RDATE" properties, and excluding any start date and times which - fall within the union of start date and times generated by any - specified "EXRULE" and "EXDATE" properties. This implies that start - date and times within exclusion related properties (i.e., "EXDATE" - and "EXRULE") take precedence over those specified by inclusion - - - - - -Dawson & Stenerson Standards Track [Page 114] - -RFC 2445 iCalendar November 1998 - - - properties (i.e., "RDATE" and "RRULE"). Where duplicate instances are - generated by the "RRULE" and "RDATE" properties, only one recurrence - is considered. Duplicate instances are ignored. - - The "EXRULE" property can be used to exclude the value specified in - "DTSTART". However, in such cases the original "DTSTART" date MUST - still be maintained by the calendaring and scheduling system because - the original "DTSTART" value has inherent usage dependencies by other - properties such as the "RECURRENCE-ID". - - Format Definition: The property is defined by the following notation: - - exrule = "EXRULE" exrparam ":" recur CRLF - - exrparam = *(";" xparam) - - Example: The following are examples of this property. Except every - other week, on Tuesday and Thursday for 4 occurrences: - - EXRULE:FREQ=WEEKLY;COUNT=4;INTERVAL=2;BYDAY=TU,TH - - Except daily for 10 occurrences: - - EXRULE:FREQ=DAILY;COUNT=10 - - Except yearly in June and July for 8 occurrences: - - EXRULE:FREQ=YEARLY;COUNT=8;BYMONTH=6,7 - -4.8.5.3 Recurrence Date/Times - - Property Name: RDATE - - Purpose: This property defines the list of date/times for a - recurrence set. - - Value Type: The default value type for this property is DATE-TIME. - The value type can be set to DATE or PERIOD. - - Property Parameters: Non-standard, value data type and time zone - identifier property parameters can be specified on this property. - - Conformance: The property can be specified in "VEVENT", "VTODO", - "VJOURNAL" or "VTIMEZONE" calendar components. - - - - - - - -Dawson & Stenerson Standards Track [Page 115] - -RFC 2445 iCalendar November 1998 - - - Description: This property can appear along with the "RRULE" property - to define an aggregate set of repeating occurrences. When they both - appear in an iCalendar object, the recurring events are defined by - the union of occurrences defined by both the "RDATE" and "RRULE". - - The recurrence dates, if specified, are used in computing the - recurrence set. The recurrence set is the complete set of recurrence - instances for a calendar component. The recurrence set is generated - by considering the initial "DTSTART" property along with the "RRULE", - "RDATE", "EXDATE" and "EXRULE" properties contained within the - iCalendar object. The "DTSTART" property defines the first instance - in the recurrence set. Multiple instances of the "RRULE" and "EXRULE" - properties can also be specified to define more sophisticated - recurrence sets. The final recurrence set is generated by gathering - all of the start date/times generated by any of the specified "RRULE" - and "RDATE" properties, and excluding any start date/times which fall - within the union of start date/times generated by any specified - "EXRULE" and "EXDATE" properties. This implies that start date/times - within exclusion related properties (i.e., "EXDATE" and "EXRULE") - take precedence over those specified by inclusion properties (i.e., - "RDATE" and "RRULE"). Where duplicate instances are generated by the - "RRULE" and "RDATE" properties, only one recurrence is considered. - Duplicate instances are ignored. - - Format Definition: The property is defined by the following notation: - - rdate = "RDATE" rdtparam ":" rdtval *("," rdtval) CRLF - - rdtparam = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - (";" "VALUE" "=" ("DATE-TIME" / "DATE" / "PERIOD")) / - (";" tzidparam) / - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) - - rdtval = date-time / date / period - ;Value MUST match value type - - Example: The following are examples of this property: - - - - -Dawson & Stenerson Standards Track [Page 116] - -RFC 2445 iCalendar November 1998 - - - RDATE:19970714T123000Z - - RDATE;TZID=US-EASTERN:19970714T083000 - - RDATE;VALUE=PERIOD:19960403T020000Z/19960403T040000Z, - 19960404T010000Z/PT3H - - RDATE;VALUE=DATE:19970101,19970120,19970217,19970421 - 19970526,19970704,19970901,19971014,19971128,19971129,19971225 - -4.8.5.4 Recurrence Rule - - Property Name: RRULE - - Purpose: This property defines a rule or repeating pattern for - recurring events, to-dos, or time zone definitions. - - Value Type: RECUR - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: This property can be specified one or more times in - recurring "VEVENT", "VTODO" and "VJOURNAL" calendar components. It - can also be specified once in each STANDARD or DAYLIGHT sub-component - of the "VTIMEZONE" calendar component. - - Description: The recurrence rule, if specified, is used in computing - the recurrence set. The recurrence set is the complete set of - recurrence instances for a calendar component. The recurrence set is - generated by considering the initial "DTSTART" property along with - the "RRULE", "RDATE", "EXDATE" and "EXRULE" properties contained - within the iCalendar object. The "DTSTART" property defines the first - instance in the recurrence set. Multiple instances of the "RRULE" and - "EXRULE" properties can also be specified to define more - sophisticated recurrence sets. The final recurrence set is generated - by gathering all of the start date/times generated by any of the - specified "RRULE" and "RDATE" properties, and excluding any start - date/times which fall within the union of start date/times generated - by any specified "EXRULE" and "EXDATE" properties. This implies that - start date/times within exclusion related properties (i.e., "EXDATE" - and "EXRULE") take precedence over those specified by inclusion - properties (i.e., "RDATE" and "RRULE"). Where duplicate instances are - generated by the "RRULE" and "RDATE" properties, only one recurrence - is considered. Duplicate instances are ignored. - - - - - - -Dawson & Stenerson Standards Track [Page 117] - -RFC 2445 iCalendar November 1998 - - - The "DTSTART" and "DTEND" property pair or "DTSTART" and "DURATION" - property pair, specified within the iCalendar object defines the - first instance of the recurrence. When used with a recurrence rule, - the "DTSTART" and "DTEND" properties MUST be specified in local time - and the appropriate set of "VTIMEZONE" calendar components MUST be - included. For detail on the usage of the "VTIMEZONE" calendar - component, see the "VTIMEZONE" calendar component definition. - - Any duration associated with the iCalendar object applies to all - members of the generated recurrence set. Any modified duration for - specific recurrences MUST be explicitly specified using the "RDATE" - property. - - Format Definition: This property is defined by the following - notation: - - rrule = "RRULE" rrulparam ":" recur CRLF - - rrulparam = *(";" xparam) - - Example: All examples assume the Eastern United States time zone. - - Daily for 10 occurrences: - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=DAILY;COUNT=10 - - ==> (1997 9:00 AM EDT)September 2-11 - - Daily until December 24, 1997: - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=DAILY;UNTIL=19971224T000000Z - - ==> (1997 9:00 AM EDT)September 2-30;October 1-25 - (1997 9:00 AM EST)October 26-31;November 1-30;December 1-23 - - Every other day - forever: - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=DAILY;INTERVAL=2 - ==> (1997 9:00 AM EDT)September2,4,6,8...24,26,28,30; - October 2,4,6...20,22,24 - (1997 9:00 AM EST)October 26,28,30;November 1,3,5,7...25,27,29; - Dec 1,3,... - - Every 10 days, 5 occurrences: - - - - -Dawson & Stenerson Standards Track [Page 118] - -RFC 2445 iCalendar November 1998 - - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=DAILY;INTERVAL=10;COUNT=5 - - ==> (1997 9:00 AM EDT)September 2,12,22;October 2,12 - - Everyday in January, for 3 years: - - DTSTART;TZID=US-Eastern:19980101T090000 - RRULE:FREQ=YEARLY;UNTIL=20000131T090000Z; - BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA - or - RRULE:FREQ=DAILY;UNTIL=20000131T090000Z;BYMONTH=1 - - ==> (1998 9:00 AM EDT)January 1-31 - (1999 9:00 AM EDT)January 1-31 - (2000 9:00 AM EDT)January 1-31 - - Weekly for 10 occurrences - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=WEEKLY;COUNT=10 - - ==> (1997 9:00 AM EDT)September 2,9,16,23,30;October 7,14,21 - (1997 9:00 AM EST)October 28;November 4 - - Weekly until December 24, 1997 - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=WEEKLY;UNTIL=19971224T000000Z - - ==> (1997 9:00 AM EDT)September 2,9,16,23,30;October 7,14,21 - (1997 9:00 AM EST)October 28;November 4,11,18,25; - December 2,9,16,23 - Every other week - forever: - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=WEEKLY;INTERVAL=2;WKST=SU - - ==> (1997 9:00 AM EDT)September 2,16,30;October 14 - (1997 9:00 AM EST)October 28;November 11,25;December 9,23 - (1998 9:00 AM EST)January 6,20;February - ... - - Weekly on Tuesday and Thursday for 5 weeks: - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=WEEKLY;UNTIL=19971007T000000Z;WKST=SU;BYDAY=TU,TH - or - - - -Dawson & Stenerson Standards Track [Page 119] - -RFC 2445 iCalendar November 1998 - - - RRULE:FREQ=WEEKLY;COUNT=10;WKST=SU;BYDAY=TU,TH - - ==> (1997 9:00 AM EDT)September 2,4,9,11,16,18,23,25,30;October 2 - - Every other week on Monday, Wednesday and Friday until December 24, - 1997, but starting on Tuesday, September 2, 1997: - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=WEEKLY;INTERVAL=2;UNTIL=19971224T000000Z;WKST=SU; - BYDAY=MO,WE,FR - ==> (1997 9:00 AM EDT)September 2,3,5,15,17,19,29;October - 1,3,13,15,17 - (1997 9:00 AM EST)October 27,29,31;November 10,12,14,24,26,28; - December 8,10,12,22 - - Every other week on Tuesday and Thursday, for 8 occurrences: - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=8;WKST=SU;BYDAY=TU,TH - - ==> (1997 9:00 AM EDT)September 2,4,16,18,30;October 2,14,16 - - Monthly on the 1st Friday for ten occurrences: - - DTSTART;TZID=US-Eastern:19970905T090000 - RRULE:FREQ=MONTHLY;COUNT=10;BYDAY=1FR - - ==> (1997 9:00 AM EDT)September 5;October 3 - (1997 9:00 AM EST)November 7;Dec 5 - (1998 9:00 AM EST)January 2;February 6;March 6;April 3 - (1998 9:00 AM EDT)May 1;June 5 - - Monthly on the 1st Friday until December 24, 1997: - - DTSTART;TZID=US-Eastern:19970905T090000 - RRULE:FREQ=MONTHLY;UNTIL=19971224T000000Z;BYDAY=1FR - - ==> (1997 9:00 AM EDT)September 5;October 3 - (1997 9:00 AM EST)November 7;December 5 - - Every other month on the 1st and last Sunday of the month for 10 - occurrences: - - DTSTART;TZID=US-Eastern:19970907T090000 - RRULE:FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=1SU,-1SU - - ==> (1997 9:00 AM EDT)September 7,28 - (1997 9:00 AM EST)November 2,30 - - - -Dawson & Stenerson Standards Track [Page 120] - -RFC 2445 iCalendar November 1998 - - - (1998 9:00 AM EST)January 4,25;March 1,29 - (1998 9:00 AM EDT)May 3,31 - - Monthly on the second to last Monday of the month for 6 months: - - DTSTART;TZID=US-Eastern:19970922T090000 - RRULE:FREQ=MONTHLY;COUNT=6;BYDAY=-2MO - - ==> (1997 9:00 AM EDT)September 22;October 20 - (1997 9:00 AM EST)November 17;December 22 - (1998 9:00 AM EST)January 19;February 16 - - Monthly on the third to the last day of the month, forever: - - DTSTART;TZID=US-Eastern:19970928T090000 - RRULE:FREQ=MONTHLY;BYMONTHDAY=-3 - - ==> (1997 9:00 AM EDT)September 28 - (1997 9:00 AM EST)October 29;November 28;December 29 - (1998 9:00 AM EST)January 29;February 26 - ... - - Monthly on the 2nd and 15th of the month for 10 occurrences: - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=MONTHLY;COUNT=10;BYMONTHDAY=2,15 - - ==> (1997 9:00 AM EDT)September 2,15;October 2,15 - (1997 9:00 AM EST)November 2,15;December 2,15 - (1998 9:00 AM EST)January 2,15 - - Monthly on the first and last day of the month for 10 occurrences: - - DTSTART;TZID=US-Eastern:19970930T090000 - RRULE:FREQ=MONTHLY;COUNT=10;BYMONTHDAY=1,-1 - - ==> (1997 9:00 AM EDT)September 30;October 1 - (1997 9:00 AM EST)October 31;November 1,30;December 1,31 - (1998 9:00 AM EST)January 1,31;February 1 - - Every 18 months on the 10th thru 15th of the month for 10 - occurrences: - - DTSTART;TZID=US-Eastern:19970910T090000 - RRULE:FREQ=MONTHLY;INTERVAL=18;COUNT=10;BYMONTHDAY=10,11,12,13,14, - 15 - - ==> (1997 9:00 AM EDT)September 10,11,12,13,14,15 - - - -Dawson & Stenerson Standards Track [Page 121] - -RFC 2445 iCalendar November 1998 - - - (1999 9:00 AM EST)March 10,11,12,13 - - Every Tuesday, every other month: - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=MONTHLY;INTERVAL=2;BYDAY=TU - - ==> (1997 9:00 AM EDT)September 2,9,16,23,30 - (1997 9:00 AM EST)November 4,11,18,25 - (1998 9:00 AM EST)January 6,13,20,27;March 3,10,17,24,31 - ... - - Yearly in June and July for 10 occurrences: - - DTSTART;TZID=US-Eastern:19970610T090000 - RRULE:FREQ=YEARLY;COUNT=10;BYMONTH=6,7 - ==> (1997 9:00 AM EDT)June 10;July 10 - (1998 9:00 AM EDT)June 10;July 10 - (1999 9:00 AM EDT)June 10;July 10 - (2000 9:00 AM EDT)June 10;July 10 - (2001 9:00 AM EDT)June 10;July 10 - Note: Since none of the BYDAY, BYMONTHDAY or BYYEARDAY components - are specified, the day is gotten from DTSTART - - Every other year on January, February, and March for 10 occurrences: - - DTSTART;TZID=US-Eastern:19970310T090000 - RRULE:FREQ=YEARLY;INTERVAL=2;COUNT=10;BYMONTH=1,2,3 - - ==> (1997 9:00 AM EST)March 10 - (1999 9:00 AM EST)January 10;February 10;March 10 - (2001 9:00 AM EST)January 10;February 10;March 10 - (2003 9:00 AM EST)January 10;February 10;March 10 - - Every 3rd year on the 1st, 100th and 200th day for 10 occurrences: - - DTSTART;TZID=US-Eastern:19970101T090000 - RRULE:FREQ=YEARLY;INTERVAL=3;COUNT=10;BYYEARDAY=1,100,200 - - ==> (1997 9:00 AM EST)January 1 - (1997 9:00 AM EDT)April 10;July 19 - (2000 9:00 AM EST)January 1 - (2000 9:00 AM EDT)April 9;July 18 - (2003 9:00 AM EST)January 1 - (2003 9:00 AM EDT)April 10;July 19 - (2006 9:00 AM EST)January 1 - - Every 20th Monday of the year, forever: - - - -Dawson & Stenerson Standards Track [Page 122] - -RFC 2445 iCalendar November 1998 - - - DTSTART;TZID=US-Eastern:19970519T090000 - RRULE:FREQ=YEARLY;BYDAY=20MO - - ==> (1997 9:00 AM EDT)May 19 - (1998 9:00 AM EDT)May 18 - (1999 9:00 AM EDT)May 17 - ... - - Monday of week number 20 (where the default start of the week is - Monday), forever: - - DTSTART;TZID=US-Eastern:19970512T090000 - RRULE:FREQ=YEARLY;BYWEEKNO=20;BYDAY=MO - - ==> (1997 9:00 AM EDT)May 12 - (1998 9:00 AM EDT)May 11 - (1999 9:00 AM EDT)May 17 - ... - - Every Thursday in March, forever: - - DTSTART;TZID=US-Eastern:19970313T090000 - RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=TH - - ==> (1997 9:00 AM EST)March 13,20,27 - (1998 9:00 AM EST)March 5,12,19,26 - (1999 9:00 AM EST)March 4,11,18,25 - ... - - Every Thursday, but only during June, July, and August, forever: - - DTSTART;TZID=US-Eastern:19970605T090000 - RRULE:FREQ=YEARLY;BYDAY=TH;BYMONTH=6,7,8 - - ==> (1997 9:00 AM EDT)June 5,12,19,26;July 3,10,17,24,31; - August 7,14,21,28 - (1998 9:00 AM EDT)June 4,11,18,25;July 2,9,16,23,30; - August 6,13,20,27 - (1999 9:00 AM EDT)June 3,10,17,24;July 1,8,15,22,29; - August 5,12,19,26 - ... - - Every Friday the 13th, forever: - - DTSTART;TZID=US-Eastern:19970902T090000 - EXDATE;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13 - - - - -Dawson & Stenerson Standards Track [Page 123] - -RFC 2445 iCalendar November 1998 - - - ==> (1998 9:00 AM EST)February 13;March 13;November 13 - (1999 9:00 AM EDT)August 13 - (2000 9:00 AM EDT)October 13 - ... - - The first Saturday that follows the first Sunday of the month, - forever: - - DTSTART;TZID=US-Eastern:19970913T090000 - RRULE:FREQ=MONTHLY;BYDAY=SA;BYMONTHDAY=7,8,9,10,11,12,13 - - ==> (1997 9:00 AM EDT)September 13;October 11 - (1997 9:00 AM EST)November 8;December 13 - (1998 9:00 AM EST)January 10;February 7;March 7 - (1998 9:00 AM EDT)April 11;May 9;June 13... - ... - - Every four years, the first Tuesday after a Monday in November, - forever (U.S. Presidential Election day): - - DTSTART;TZID=US-Eastern:19961105T090000 - RRULE:FREQ=YEARLY;INTERVAL=4;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4, - 5,6,7,8 - - ==> (1996 9:00 AM EST)November 5 - (2000 9:00 AM EST)November 7 - (2004 9:00 AM EST)November 2 - ... - - The 3rd instance into the month of one of Tuesday, Wednesday or - Thursday, for the next 3 months: - - DTSTART;TZID=US-Eastern:19970904T090000 - RRULE:FREQ=MONTHLY;COUNT=3;BYDAY=TU,WE,TH;BYSETPOS=3 - - ==> (1997 9:00 AM EDT)September 4;October 7 - (1997 9:00 AM EST)November 6 - - The 2nd to last weekday of the month: - - DTSTART;TZID=US-Eastern:19970929T090000 - RRULE:FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-2 - - ==> (1997 9:00 AM EDT)September 29 - (1997 9:00 AM EST)October 30;November 27;December 30 - (1998 9:00 AM EST)January 29;February 26;March 30 - ... - - - - -Dawson & Stenerson Standards Track [Page 124] - -RFC 2445 iCalendar November 1998 - - - Every 3 hours from 9:00 AM to 5:00 PM on a specific day: - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=HOURLY;INTERVAL=3;UNTIL=19970902T170000Z - - ==> (September 2, 1997 EDT)09:00,12:00,15:00 - - Every 15 minutes for 6 occurrences: - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=MINUTELY;INTERVAL=15;COUNT=6 - - ==> (September 2, 1997 EDT)09:00,09:15,09:30,09:45,10:00,10:15 - - Every hour and a half for 4 occurrences: - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=MINUTELY;INTERVAL=90;COUNT=4 - - ==> (September 2, 1997 EDT)09:00,10:30;12:00;13:30 - - Every 20 minutes from 9:00 AM to 4:40 PM every day: - - DTSTART;TZID=US-Eastern:19970902T090000 - RRULE:FREQ=DAILY;BYHOUR=9,10,11,12,13,14,15,16;BYMINUTE=0,20,40 - or - RRULE:FREQ=MINUTELY;INTERVAL=20;BYHOUR=9,10,11,12,13,14,15,16 - - ==> (September 2, 1997 EDT)9:00,9:20,9:40,10:00,10:20, - ... 16:00,16:20,16:40 - (September 3, 1997 EDT)9:00,9:20,9:40,10:00,10:20, - ...16:00,16:20,16:40 - ... - - An example where the days generated makes a difference because of - WKST: - - DTSTART;TZID=US-Eastern:19970805T090000 - RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=MO - - ==> (1997 EDT)Aug 5,10,19,24 - - changing only WKST from MO to SU, yields different results... - - DTSTART;TZID=US-Eastern:19970805T090000 - RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=SU - ==> (1997 EDT)August 5,17,19,31 - - - - -Dawson & Stenerson Standards Track [Page 125] - -RFC 2445 iCalendar November 1998 - - -4.8.6 Alarm Component Properties - - The following properties specify alarm information in calendar - components. - -4.8.6.1 Action - - Property Name: ACTION - - Purpose: This property defines the action to be invoked when an alarm - is triggered. - - Value Type: TEXT - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: This property MUST be specified once in a "VALARM" - calendar component. - - Description: Each "VALARM" calendar component has a particular type - of action associated with it. This property specifies the type of - action - - Format Definition: The property is defined by the following notation: - - action = "ACTION" actionparam ":" actionvalue CRLF - - actionparam = *(";" xparam) - - actionvalue = "AUDIO" / "DISPLAY" / "EMAIL" / "PROCEDURE" - / iana-token / x-name - - Example: The following are examples of this property in a "VALARM" - calendar component: - - ACTION:AUDIO - - ACTION:DISPLAY - - ACTION:PROCEDURE - -4.8.6.2 Repeat Count - - Property Name: REPEAT - - Purpose: This property defines the number of time the alarm should be - repeated, after the initial trigger. - - - -Dawson & Stenerson Standards Track [Page 126] - -RFC 2445 iCalendar November 1998 - - - Value Type: INTEGER - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: This property can be specified in a "VALARM" calendar - component. - - Description: If the alarm triggers more than once, then this property - MUST be specified along with the "DURATION" property. - - Format Definition: The property is defined by the following notation: - - repeatcnt = "REPEAT" repparam ":" integer CRLF - ;Default is "0", zero. - - repparam = *(";" xparam) - - Example: The following is an example of this property for an alarm - that repeats 4 additional times with a 5 minute delay after the - initial triggering of the alarm: - - REPEAT:4 - DURATION:PT5M - -4.8.6.3 Trigger - - Property Name: TRIGGER - - Purpose: This property specifies when an alarm will trigger. - - Value Type: The default value type is DURATION. The value type can be - set to a DATE-TIME value type, in which case the value MUST specify a - UTC formatted DATE-TIME value. - - Property Parameters: Non-standard, value data type, time zone - identifier or trigger relationship property parameters can be - specified on this property. The trigger relationship property - parameter MUST only be specified when the value type is DURATION. - - Conformance: This property MUST be specified in the "VALARM" calendar - component. - - Description: Within the "VALARM" calendar component, this property - defines when the alarm will trigger. The default value type is - DURATION, specifying a relative time for the trigger of the alarm. - The default duration is relative to the start of an event or to-do - that the alarm is associated with. The duration can be explicitly set - - - -Dawson & Stenerson Standards Track [Page 127] - -RFC 2445 iCalendar November 1998 - - - to trigger from either the end or the start of the associated event - or to-do with the "RELATED" parameter. A value of START will set the - alarm to trigger off the start of the associated event or to-do. A - value of END will set the alarm to trigger off the end of the - associated event or to-do. - - Either a positive or negative duration may be specified for the - "TRIGGER" property. An alarm with a positive duration is triggered - after the associated start or end of the event or to-do. An alarm - with a negative duration is triggered before the associated start or - end of the event or to-do. - - The "RELATED" property parameter is not valid if the value type of - the property is set to DATE-TIME (i.e., for an absolute date and time - alarm trigger). If a value type of DATE-TIME is specified, then the - property value MUST be specified in the UTC time format. If an - absolute trigger is specified on an alarm for a recurring event or - to-do, then the alarm will only trigger for the specified absolute - date/time, along with any specified repeating instances. - - If the trigger is set relative to START, then the "DTSTART" property - MUST be present in the associated "VEVENT" or "VTODO" calendar - component. If an alarm is specified for an event with the trigger set - relative to the END, then the "DTEND" property or the "DSTART" and - "DURATION' properties MUST be present in the associated "VEVENT" - calendar component. If the alarm is specified for a to-do with a - trigger set relative to the END, then either the "DUE" property or - the "DSTART" and "DURATION' properties MUST be present in the - associated "VTODO" calendar component. - - Alarms specified in an event or to-do which is defined in terms of a - DATE value type will be triggered relative to 00:00:00 UTC on the - specified date. For example, if "DTSTART:19980205, then the duration - trigger will be relative to19980205T000000Z. - - Format Definition: The property is defined by the following notation: - - trigger = "TRIGGER" (trigrel / trigabs) - - trigrel = *( - - ; the following are optional, - ; but MUST NOT occur more than once - - (";" "VALUE" "=" "DURATION") / - (";" trigrelparam) / - - ; the following is optional, - - - -Dawson & Stenerson Standards Track [Page 128] - -RFC 2445 iCalendar November 1998 - - - ; and MAY occur more than once - - (";" xparam) - ) ":" dur-value - - trigabs = 1*( - - ; the following is REQUIRED, - ; but MUST NOT occur more than once - - (";" "VALUE" "=" "DATE-TIME") / - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) ":" date-time - - Example: A trigger set 15 minutes prior to the start of the event or - to-do. - - TRIGGER:-P15M - - A trigger set 5 minutes after the end of the event or to-do. - - TRIGGER;RELATED=END:P5M - - A trigger set to an absolute date/time. - - TRIGGER;VALUE=DATE-TIME:19980101T050000Z - -4.8.7 Change Management Component Properties - - The following properties specify change management information in - calendar components. - -4.8.7.1 Date/Time Created - - Property Name: CREATED - - Purpose: This property specifies the date and time that the calendar - information was created by the calendar user agent in the calendar - store. - - Note: This is analogous to the creation date and time for a file - in the file system. - - - - -Dawson & Stenerson Standards Track [Page 129] - -RFC 2445 iCalendar November 1998 - - - Value Type: DATE-TIME - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: The property can be specified once in "VEVENT", "VTODO" - or "VJOURNAL" calendar components. - - Description: The date and time is a UTC value. - - Format Definition: The property is defined by the following notation: - - created = "CREATED" creaparam ":" date-time CRLF - - creaparam = *(";" xparam) - - Example: The following is an example of this property: - - CREATED:19960329T133000Z - -4.8.7.2 Date/Time Stamp - - Property Name: DTSTAMP - - Purpose: The property indicates the date/time that the instance of - the iCalendar object was created. - - Value Type: DATE-TIME - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: This property MUST be included in the "VEVENT", "VTODO", - "VJOURNAL" or "VFREEBUSY" calendar components. - - Description: The value MUST be specified in the UTC time format. - - This property is also useful to protocols such as [IMIP] that have - inherent latency issues with the delivery of content. This property - will assist in the proper sequencing of messages containing iCalendar - objects. - - This property is different than the "CREATED" and "LAST-MODIFIED" - properties. These two properties are used to specify when the - particular calendar data in the calendar store was created and last - modified. This is different than when the iCalendar object - representation of the calendar service information was created or - last modified. - - - -Dawson & Stenerson Standards Track [Page 130] - -RFC 2445 iCalendar November 1998 - - - Format Definition: The property is defined by the following notation: - - dtstamp = "DTSTAMP" stmparam ":" date-time CRLF - - stmparam = *(";" xparam) - - Example: - - DTSTAMP:19971210T080000Z - -4.8.7.3 Last Modified - - Property Name: LAST-MODIFIED - - Purpose: The property specifies the date and time that the - information associated with the calendar component was last revised - in the calendar store. - - Note: This is analogous to the modification date and time for a - file in the file system. - - Value Type: DATE-TIME - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: This property can be specified in the "EVENT", "VTODO", - "VJOURNAL" or "VTIMEZONE" calendar components. - - Description: The property value MUST be specified in the UTC time - format. - - Format Definition: The property is defined by the following notation: - - last-mod = "LAST-MODIFIED" lstparam ":" date-time CRLF - - lstparam = *(";" xparam) - - Example: The following is are examples of this property: - - LAST-MODIFIED:19960817T133000Z - -4.8.7.4 Sequence Number - - Property Name: SEQUENCE - - Purpose: This property defines the revision sequence number of the - calendar component within a sequence of revisions. - - - -Dawson & Stenerson Standards Track [Page 131] - -RFC 2445 iCalendar November 1998 - - - Value Type: integer - - Property Parameters: Non-standard property parameters can be - specified on this property. - - Conformance: The property can be specified in "VEVENT", "VTODO" or - "VJOURNAL" calendar component. - - Description: When a calendar component is created, its sequence - number is zero (US-ASCII decimal 48). It is monotonically incremented - by the "Organizer's" CUA each time the "Organizer" makes a - significant revision to the calendar component. When the "Organizer" - makes changes to one of the following properties, the sequence number - MUST be incremented: - - . "DTSTART" - - . "DTEND" - - . "DUE" - - . "RDATE" - - . "RRULE" - - . "EXDATE" - - . "EXRULE" - - . "STATUS" - - In addition, changes made by the "Organizer" to other properties can - also force the sequence number to be incremented. The "Organizer" CUA - MUST increment the sequence number when ever it makes changes to - properties in the calendar component that the "Organizer" deems will - jeopardize the validity of the participation status of the - "Attendees". For example, changing the location of a meeting from one - locale to another distant locale could effectively impact the - participation status of the "Attendees". - - The "Organizer" includes this property in an iCalendar object that it - sends to an "Attendee" to specify the current version of the calendar - component. - - The "Attendee" includes this property in an iCalendar object that it - sends to the "Organizer" to specify the version of the calendar - component that the "Attendee" is referring to. - - - - -Dawson & Stenerson Standards Track [Page 132] - -RFC 2445 iCalendar November 1998 - - - A change to the sequence number is not the mechanism that an - "Organizer" uses to request a response from the "Attendees". The - "RSVP" parameter on the "ATTENDEE" property is used by the - "Organizer" to indicate that a response from the "Attendees" is - requested. - - Format Definition: This property is defined by the following - notation: - - seq = "SEQUENCE" seqparam ":" integer CRLF - ; Default is "0" - - seqparam = *(";" xparam) - - Example: The following is an example of this property for a calendar - component that was just created by the "Organizer". - - SEQUENCE:0 - - The following is an example of this property for a calendar component - that has been revised two different times by the "Organizer". - - SEQUENCE:2 - -4.8.8 Miscellaneous Component Properties - - The following properties specify information about a number of - miscellaneous features of calendar components. - -4.8.8.1 Non-standard Properties - - Property Name: Any property name with a "X-" prefix - - Purpose: This class of property provides a framework for defining - non-standard properties. - - Value Type: TEXT - - Property Parameters: Non-standard and language property parameters - can be specified on this property. - - Conformance: This property can be specified in any calendar - component. - - Description: The MIME Calendaring and Scheduling Content Type - provides a "standard mechanism for doing non-standard things". This - extension support is provided for implementers to "push the envelope" - on the existing version of the memo. Extension properties are - - - -Dawson & Stenerson Standards Track [Page 133] - -RFC 2445 iCalendar November 1998 - - - specified by property and/or property parameter names that have the - prefix text of "X-" (the two character sequence: LATIN CAPITAL LETTER - X character followed by the HYPEN-MINUS character). It is recommended - that vendors concatenate onto this sentinel another short prefix text - to identify the vendor. This will facilitate readability of the - extensions and minimize possible collision of names between different - vendors. User agents that support this content type are expected to - be able to parse the extension properties and property parameters but - can ignore them. - - At present, there is no registration authority for names of extension - properties and property parameters. The data type for this property - is TEXT. Optionally, the data type can be any of the other valid data - types. - - Format Definition: The property is defined by the following notation: - - x-prop = x-name *(";" xparam) [";" languageparam] ":" text CRLF - ; Lines longer than 75 octets should be folded - - Example: The following might be the ABC vendor's extension for an - audio-clip form of subject property: - - X-ABC-MMSUBJ;X-ABC-MMSUBJTYPE=wave:http://load.noise.org/mysubj.wav - -4.8.8.2 Request Status - - Property Name: REQUEST-STATUS - - Purpose: This property defines the status code returned for a - scheduling request. - - Value Type: TEXT - - Property Parameters: Non-standard and language property parameters - can be specified on this property. - - Conformance: The property can be specified in "VEVENT", "VTODO", - "VJOURNAL" or "VFREEBUSY" calendar component. - - Description: This property is used to return status code information - related to the processing of an associated iCalendar object. The data - type for this property is TEXT. - - The value consists of a short return status component, a longer - return status description component, and optionally a status-specific - data component. The components of the value are separated by the - SEMICOLON character (US-ASCII decimal 59). - - - -Dawson & Stenerson Standards Track [Page 134] - -RFC 2445 iCalendar November 1998 - - - The short return status is a PERIOD character (US-ASCII decimal 46) - separated 3-tuple of integers. For example, "3.1.1". The successive - levels of integers provide for a successive level of status code - granularity. - - The following are initial classes for the return status code. - Individual iCalendar object methods will define specific return - status codes for these classes. In addition, other classes for the - return status code may be defined using the registration process - defined later in this memo. - - |==============+===============================================| - | Short Return | Longer Return Status Description | - | Status Code | | - |==============+===============================================| - | 1.xx | Preliminary success. This class of status | - | | of status code indicates that the request has | - | | request has been initially processed but that | - | | completion is pending. | - |==============+===============================================| - | 2.xx | Successful. This class of status code | - | | indicates that the request was completed | - | | successfuly. However, the exact status code | - | | can indicate that a fallback has been taken. | - |==============+===============================================| - | 3.xx | Client Error. This class of status code | - | | indicates that the request was not successful.| - | | The error is the result of either a syntax or | - | | a semantic error in the client formatted | - | | request. Request should not be retried until | - | | the condition in the request is corrected. | - |==============+===============================================| - | 4.xx | Scheduling Error. This class of status code | - | | indicates that the request was not successful.| - | | Some sort of error occurred within the | - | | calendaring and scheduling service, not | - | | directly related to the request itself. | - |==============+===============================================| - - Format Definition: The property is defined by the following notation: - - rstatus = "REQUEST-STATUS" rstatparam ":" - statcode ";" statdesc [";" extdata] - - rstatparam = *( - - ; the following is optional, - ; but MUST NOT occur more than once - - - -Dawson & Stenerson Standards Track [Page 135] - -RFC 2445 iCalendar November 1998 - - - (";" languageparm) / - - ; the following is optional, - ; and MAY occur more than once - - (";" xparam) - - ) - - statcode = 1*DIGIT *("." 1*DIGIT) - ;Hierarchical, numeric return status code - - statdesc = text - ;Textual status description - - extdata = text - ;Textual exception data. For example, the offending property - ;name and value or complete property line. - - Example: The following are some possible examples of this property. - The COMMA and SEMICOLON separator characters in the property value - are BACKSLASH character escaped because they appear in a text value. - - REQUEST-STATUS:2.0;Success - - REQUEST-STATUS:3.1;Invalid property value;DTSTART:96-Apr-01 - - REQUEST-STATUS:2.8; Success\, repeating event ignored. Scheduled - as a single event.;RRULE:FREQ=WEEKLY\;INTERVAL=2 - - REQUEST-STATUS:4.1;Event conflict. Date/time is busy. - - REQUEST-STATUS:3.7;Invalid calendar user;ATTENDEE: - MAILTO:jsmith@host.com - -5 iCalendar Object Examples - - The following examples are provided as an informational source of - illustrative iCalendar objects consistent with this content type. - - The following example specifies a three-day conference that begins at - 8:00 AM EDT, September 18, 1996 and end at 6:00 PM EDT, September 20, - 1996. - - BEGIN:VCALENDAR PRODID:-//xyz Corp//NONSGML PDA Calendar Verson - 1.0//EN VERSION:2.0 BEGIN:VEVENT DTSTAMP:19960704T120000Z - UID:uid1@host.com ORGANIZER:MAILTO:jsmith@host.com - DTSTART:19960918T143000Z DTEND:19960920T220000Z STATUS:CONFIRMED - - - -Dawson & Stenerson Standards Track [Page 136] - -RFC 2445 iCalendar November 1998 - - - CATEGORIES:CONFERENCE SUMMARY:Networld+Interop Conference - DESCRIPTION:Networld+Interop Conference - and Exhibit\nAtlanta World Congress Center\n - Atlanta, Georgia END:VEVENT END:VCALENDAR - - The following example specifies a group scheduled meeting that begin - at 8:30 AM EST on March 12, 1998 and end at 9:30 AM EST on March 12, - 1998. The "Organizer" has scheduled the meeting with one or more - calendar users in a group. A time zone specification for Eastern - United States has been specified. - - BEGIN:VCALENDAR - PRODID:-//RDU Software//NONSGML HandCal//EN - VERSION:2.0 - BEGIN:VTIMEZONE - TZID:US-Eastern - BEGIN:STANDARD - DTSTART:19981025T020000 - RDATE:19981025T020000 - TZOFFSETFROM:-0400 - TZOFFSETTO:-0500 - TZNAME:EST - END:STANDARD - BEGIN:DAYLIGHT - DTSTART:19990404T020000 - RDATE:19990404T020000 - TZOFFSETFROM:-0500 - TZOFFSETTO:-0400 - TZNAME:EDT - END:DAYLIGHT - END:VTIMEZONE - BEGIN:VEVENT - DTSTAMP:19980309T231000Z - UID:guid-1.host1.com - ORGANIZER;ROLE=CHAIR:MAILTO:mrbig@host.com - ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT;CUTYPE=GROUP: - MAILTO:employee-A@host.com - DESCRIPTION:Project XYZ Review Meeting - CATEGORIES:MEETING - CLASS:PUBLIC - CREATED:19980309T130000Z - SUMMARY:XYZ Project Review - DTSTART;TZID=US-Eastern:19980312T083000 - DTEND;TZID=US-Eastern:19980312T093000 - LOCATION:1CP Conference Room 4350 - END:VEVENT - END:VCALENDAR - - - - -Dawson & Stenerson Standards Track [Page 137] - -RFC 2445 iCalendar November 1998 - - - The following is an example of an iCalendar object passed in a MIME - message with a single body part consisting of a "text/calendar" - Content Type. - - TO:jsmith@host1.com - FROM:jdoe@host1.com - MIME-VERSION:1.0 - MESSAGE-ID: - CONTENT-TYPE:text/calendar - - BEGIN:VCALENDAR - METHOD:xyz - VERSION:2.0 - PRODID:-//ABC Corporation//NONSGML My Product//EN - BEGIN:VEVENT - DTSTAMP:19970324T1200Z - SEQUENCE:0 - UID:uid3@host1.com - ORGANIZER:MAILTO:jdoe@host1.com - ATTENDEE;RSVP=TRUE:MAILTO:jsmith@host1.com - DTSTART:19970324T123000Z - DTEND:19970324T210000Z - CATEGORIES:MEETING,PROJECT - CLASS:PUBLIC - SUMMARY:Calendaring Interoperability Planning Meeting - DESCRIPTION:Discuss how we can test c&s interoperability\n - using iCalendar and other IETF standards. - LOCATION:LDB Lobby - ATTACH;FMTTYPE=application/postscript:ftp://xyzCorp.com/pub/ - conf/bkgrnd.ps - END:VEVENT - END:VCALENDAR - - The following is an example of a to-do due on April 15, 1998. An - audio alarm has been specified to remind the calendar user at noon, - the day before the to-do is expected to be completed and repeat - hourly, four additional times. The to-do definition has been modified - twice since it was initially created. - - BEGIN:VCALENDAR - VERSION:2.0 - PRODID:-//ABC Corporation//NONSGML My Product//EN - BEGIN:VTODO - DTSTAMP:19980130T134500Z - SEQUENCE:2 - UID:uid4@host1.com - ORGANIZER:MAILTO:unclesam@us.gov - ATTENDEE;PARTSTAT=ACCEPTED:MAILTO:jqpublic@host.com - - - -Dawson & Stenerson Standards Track [Page 138] - -RFC 2445 iCalendar November 1998 - - - DUE:19980415T235959 - STATUS:NEEDS-ACTION - SUMMARY:Submit Income Taxes - BEGIN:VALARM - ACTION:AUDIO - TRIGGER:19980403T120000 - ATTACH;FMTTYPE=audio/basic:http://host.com/pub/audio- - files/ssbanner.aud - REPEAT:4 - DURATION:PT1H - END:VALARM - END:VTODO - END:VCALENDAR - - The following is an example of a journal entry. - - BEGIN:VCALENDAR - VERSION:2.0 - PRODID:-//ABC Corporation//NONSGML My Product//EN - BEGIN:VJOURNAL - DTSTAMP:19970324T120000Z - UID:uid5@host1.com - ORGANIZER:MAILTO:jsmith@host.com - STATUS:DRAFT - CLASS:PUBLIC - CATEGORY:Project Report, XYZ, Weekly Meeting - DESCRIPTION:Project xyz Review Meeting Minutes\n - Agenda\n1. Review of project version 1.0 requirements.\n2. - Definition - of project processes.\n3. Review of project schedule.\n - Participants: John Smith, Jane Doe, Jim Dandy\n-It was - decided that the requirements need to be signed off by - product marketing.\n-Project processes were accepted.\n - -Project schedule needs to account for scheduled holidays - and employee vacation time. Check with HR for specific - dates.\n-New schedule will be distributed by Friday.\n- - Next weeks meeting is cancelled. No meeting until 3/23. - END:VJOURNAL - END:VCALENDAR - - The following is an example of published busy time information. The - iCalendar object might be placed in the network resource - www.host.com/calendar/busytime/jsmith.ifb. - - BEGIN:VCALENDAR - VERSION:2.0 - PRODID:-//RDU Software//NONSGML HandCal//EN - BEGIN:VFREEBUSY - - - -Dawson & Stenerson Standards Track [Page 139] - -RFC 2445 iCalendar November 1998 - - - ORGANIZER:MAILTO:jsmith@host.com - DTSTART:19980313T141711Z - DTEND:19980410T141711Z - FREEBUSY:19980314T233000Z/19980315T003000Z - FREEBUSY:19980316T153000Z/19980316T163000Z - FREEBUSY:19980318T030000Z/19980318T040000Z - URL:http://www.host.com/calendar/busytime/jsmith.ifb - END:VFREEBUSY - END:VCALENDAR - -6 Recommended Practices - - These recommended practices should be followed in order to assure - consistent handling of the following cases for an iCalendar object. - - 1. Content lines longer than 75 octets SHOULD be folded. - - 2. A calendar entry with a "DTSTART" property but no "DTEND" - property does not take up any time. It is intended to represent - an event that is associated with a given calendar date and time - of day, such as an anniversary. Since the event does not take up - any time, it MUST NOT be used to record busy time no matter what - the value for the "TRANSP" property. - - 3. When the "DTSTART" and "DTEND", for "VEVENT", "VJOURNAL" and - "VFREEBUSY" calendar components, and "DTSTART" and "DUE", for - "VTODO" calendar components, have the same value data type (e.g., - DATE-TIME), they SHOULD specify values in the same time format - (e.g., UTC time format). - - 4. When the combination of the "RRULE" and "RDATE" properties on an - iCalendar object produces multiple instances having the same - start date/time, they should be collapsed to, and considered as, - a single instance. - - 5. When a calendar user receives multiple requests for the same - calendar component (e.g., REQUEST for a "VEVENT" calendar - component) as a result of being on multiple mailing lists - specified by "ATTENDEE" properties in the request, they SHOULD - respond to only one of the requests. The calendar user SHOULD - also specify (using the "MEMBER" parameter of the "ATTENDEE" - property) which mailing list they are a member of. - - 6. An implementation can truncate a "SUMMARY" property value to 255 - characters. - - - - - - -Dawson & Stenerson Standards Track [Page 140] - -RFC 2445 iCalendar November 1998 - - - 7. If seconds of the minute are not supported by an implementation, - then a value of "00" SHOULD be specified for the seconds - component in a time value. - - 8. If the value type parameter (VALUE=) contains an unknown value - type, it SHOULD be treated as TEXT. - - 9. TZURL values SHOULD NOT be specified as a FILE URI type. This URI - form can be useful within an organization, but is problematic in - the Internet. - - 10. Some possible English values for CATEGORIES property include - "ANNIVERSARY", "APPOINTMENT", "BUSINESS", "EDUCATION", - "HOLIDAY", "MEETING", "MISCELLANEOUS", "NON-WORKING HOURS", "NOT - IN OFFICE", "PERSONAL", "PHONE CALL", "SICK DAY", "SPECIAL - OCCASION", "TRAVEL", "VACATION". Categories can be specified in - any registered language. - - 11. Some possible English values for RESOURCES property include - "CATERING", "CHAIRS", "COMPUTER PROJECTOR", "EASEL", "OVERHEAD - PROJECTOR", "SPEAKER PHONE", "TABLE", "TV", "VCR", "VIDEO - PHONE", "VEHICLE". Resources can be specified in any registered - language. - -7 Registration of Content Type Elements - - This section provides the process for registration of MIME - Calendaring and Scheduling Content Type iCalendar object methods and - new or modified properties. - -7.1 Registration of New and Modified iCalendar Object Methods - - New MIME Calendaring and Scheduling Content Type iCalendar object - methods are registered by the publication of an IETF Request for - Comments (RFC). Changes to an iCalendar object method are registered - by the publication of a revision of the RFC defining the method. - -7.2 Registration of New Properties - - This section defines procedures by which new properties or enumerated - property values for the MIME Calendaring and Scheduling Content Type - can be registered with the IANA. Non-IANA properties can be used by - bilateral agreement, provided the associated properties names follow - the "X-" convention. - - The procedures defined here are designed to allow public comment and - review of new properties, while posing only a small impediment to the - definition of new properties. - - - -Dawson & Stenerson Standards Track [Page 141] - -RFC 2445 iCalendar November 1998 - - - Registration of a new property is accomplished by the following - steps. - -7.2.1 Define the property - - A property is defined by completing the following template. - - To: ietf-calendar@imc.org - - Subject: Registration of text/calendar MIME property XXX - - Property name: - - Property purpose: - - Property value type(s): - - Property parameter (s): - - Conformance: - - Description: - - Format definition: - - Examples: - - The meaning of each field in the template is as follows. - - Property name: The name of the property, as it will appear in the - body of an text/calendar MIME Content-Type "property: value" line to - the left of the colon ":". - - Property purpose: The purpose of the property (e.g., to indicate a - delegate for the event or to-do, etc.). Give a short but clear - description. - - Property value type (s): Any of the valid value types for the - property value needs to be specified. The default value type also - needs to be specified. If a new value type is specified, it needs to - be declared in this section. - - Property parameter (s): Any of the valid property parameters for the - property needs to be specified. - - Conformance: The calendar components that the property can appear in - needs to be specified. - - - - -Dawson & Stenerson Standards Track [Page 142] - -RFC 2445 iCalendar November 1998 - - - Description: Any special notes about the property, how it is to be - used, etc. - - Format definition: The ABNF for the property definition needs to be - specified. - - Examples: One or more examples of instances of the property needs to - be specified. - -7.2.2 Post the Property definition - - The property description MUST be posted to the new property - discussion list, ietf-calendar@imc.org. - -7.2.3 Allow a comment period - - Discussion on the new property MUST be allowed to take place on the - list for a minimum of two weeks. Consensus MUST be reached on the - property before proceeding to the next step. - -7.2.4 Submit the property for approval - - Once the two-week comment period has elapsed, and the proposer is - convinced consensus has been reached on the property, the - registration application should be submitted to the Method Reviewer - for approval. The Method Reviewer is appointed to the Application - Area Directors and can either accept or reject the property - registration. An accepted registration should be passed on by the - Method Reviewer to the IANA for inclusion in the official IANA method - registry. The registration can be rejected for any of the following - reasons. 1) Insufficient comment period; 2) Consensus not reached; 3) - Technical deficiencies raised on the list or elsewhere have not been - addressed. The Method Reviewer's decision to reject a property can be - appealed by the proposer to the IESG, or the objections raised can be - addressed by the proposer and the property resubmitted. - -7.3 Property Change Control - - Existing properties can be changed using the same process by which - they were registered. - - 1. Define the change - - 2. Post the change - - 3. Allow a comment period - - 4. Submit the property for approval - - - -Dawson & Stenerson Standards Track [Page 143] - -RFC 2445 iCalendar November 1998 - - - Note that the original author or any other interested party can - propose a change to an existing property, but that such changes - should only be proposed when there are serious omissions or errors in - the published memo. The Method Reviewer can object to a change if it - is not backward compatible, but is not required to do so. - - Property definitions can never be deleted from the IANA registry, but - properties which are no longer believed to be useful can be declared - OBSOLETE by a change to their "intended use" field. - -8 References - - [IMIP] Dawson, F., Mansour, S. and S. Silverberg, "iCalendar - Message-based Interoperability Protocol (IMIP)", RFC 2447, - November 1998. - - [ITIP] Silverberg, S., Mansour, S., Dawson, F. and R. Hopson, - "iCalendar Transport-Independent Interoperability Protocol - (iTIP) : Scheduling Events, Busy Time, To-dos and Journal - Entries", RFC 2446, November 1998. - - [ISO 8601] ISO 8601, "Data elements and interchange formats- - Information interchange--Representation of dates and - times", International Organization for Standardization, - June, 1988. - - [ISO 9070] ISO/IEC 9070, "Information Technology_SGML Support - Facilities--Registration Procedures for Public Text Owner - Identifiers", Second Edition, International Organization - for Standardization, April 1991. - - [RFC 822] Crocker, D., "Standard for the Format of ARPA Internet - Text Messages", STD 11, RFC 822, August 1982. - - [RFC 1738] Berners-Lee, T., Masinter, L. and M. McCahill, "Uniform - Resource Locators (URL)", RFC 1738, December 1994. - - [RFC 1766] Alvestrand, H., "Tags for the Identification of - Languages", RFC 1766, March 1995. - - [RFC 2045] Freed, N. and N. Borenstein, " Multipurpose Internet Mail - Extensions (MIME) - Part One: Format of Internet Message - Bodies", RFC 2045, November 1996. - - [RFC 2046] Freed, N. and N. Borenstein, " Multipurpose Internet Mail - Extensions (MIME) - Part Two: Media Types", RFC 2046, - November 1996. - - - - -Dawson & Stenerson Standards Track [Page 144] - -RFC 2445 iCalendar November 1998 - - - [RFC 2048] Freed, N., Klensin, J. and J. Postel, "Multipurpose - Internet Mail Extensions (MIME) - Part Four: Registration - Procedures", RFC 2048, January 1997. - - [RFC 2119] Bradner, S., "Key words for use in RFCs to Indicate - Requirement Levels", BCP 14, RFC 2119, March 1997. - - [RFC 2234] Crocker, D. and P. Overell, "Augmented BNF for Syntax - Specifications: ABNF", RFC 2234, November 1997. - - [RFC 2279] Yergeau, F., "UTF-8, a transformation format of ISO - 10646", RFC 2279, January 1998. - - [RFC 2425] Howes, T., Smith, M. and F. Dawson, "A MIME Content-Type - for Directory Information", RFC 2425, September 1998. - - [RFC 2426] Dawson, F. and T. Howes, "vCard MIME Directory Profile", - RFC 2426, September 1998. - - [TZ] Olson, A.D., et al, Time zone code and data, - ftp://elsie.nci.nih.gov/pub/, updated periodically. - - [VCAL] Internet Mail Consortium, "vCalendar - The Electronic - Calendaring and Scheduling Exchange Format", - http://www.imc.org/pdi/vcal-10.txt, September 18, 1996. - -9 Acknowledgments - - A hearty thanks to the IETF Calendaring and Scheduling Working Group - and also the following individuals who have participated in the - drafting, review and discussion of this memo: - - Roland Alden, Harald T. Alvestrand, Eric Berman, Denis Bigorgne, John - Binici, Bill Bliss, Philippe Boucher, Steve Carter, Andre - Courtemanche, Dave Crocker, David Curley, Alec Dun, John Evans, Ross - Finlayson, Randell Flint, Ned Freed, Patrik Faltstrom, Chuck - Grandgent, Mark Handley, Steve Hanna, Paul B. Hill, Paul Hoffman, - Ross Hopson, Mark Horton, Daryl Huff, Bruce Kahn, C. Harald Koch, - Ryan Jansen, Don Lavange, Antoine Leca, Theodore Lorek, Steve - Mansour, Skip Montanaro, Keith Moore, Cecil Murray, Chris Newman, - John Noerenberg, Ralph Patterson, Pete Resnick, Keith Rhodes, Robert - Ripberger, John Rose, Doug Royer, Andras Salamar, Ted Schuh, Vinod - Seraphin, Derrick Shadel, Ken Shan, Andrew Shuman, Steve Silverberg, - William P. Spencer, John Sun, Mark Towfiq, Yvonne Tso, Robert Visnov, - James L. Weiner, Mike Weston, William Wyatt. - - - - - - -Dawson & Stenerson Standards Track [Page 145] - -RFC 2445 iCalendar November 1998 - - -10 Authors' and Chairs' Addresses - - The following address information is provided in a MIME-VCARD, - Electronic Business Card, format. - - The authors of this memo are: - - BEGIN:VCARD - VERSION:3.0 - N:Dawson;Frank - FN:Frank Dawson - ORG:Lotus Development Corporation - ADR;TYPE=WORK,POSTAL,PARCEL:;;6544 Battleford Drive; - Raleigh;NC;27613-3502;USA - TEL;TYPE=WORK,MSG:+1-919-676-9515 - TEL;TYPE=WORK,FAX:+1-919-676-9564 - EMAIL;TYPE=PREF,INTERNET:Frank_Dawson@Lotus.com - EMAIL;TYPE=INTERNET:fdawson@earthlink.net - URL:http://home.earthlink.net/~fdawson - END:VCARD - - BEGIN:VCARD - VERSION:3.0 - N:Stenerson;Derik - FN:Derik Stenerson - ORG:Microsoft Corporation - ADR;TYPE=WORK,POSTAL,PARCEL:;;One Microsoft Way; - Redmond;WA;98052-6399;USA - TEL;TYPE=WORK,MSG:+1-425-936-5522 - TEL;TYPE=WORK,FAX:+1-425-936-7329 - EMAIL;TYPE=INTERNET:deriks@Microsoft.com - END:VCARD - - The iCalendar object is a result of the work of the Internet - Engineering Task Force Calendaring and Scheduling Working Group. The - chairmen of that working group are: - - BEGIN:VCARD - VERSION:3.0 - N:Ganguly;Anik - FN:Anik Ganguly - ORG: Open Text Inc. - ADR;TYPE=WORK,POSTAL,PARCEL:;Suite 101;38777 West Six Mile Road; - Livonia;MI;48152;USA - TEL;TYPE=WORK,MSG:+1-734-542-5955 - EMAIL;TYPE=INTERNET:ganguly@acm.org - END:VCARD - - - - -Dawson & Stenerson Standards Track [Page 146] - -RFC 2445 iCalendar November 1998 - - - The co-chairman of that working group is: - - BEGIN:VCARD - VERSION:3.0 - N:Moskowitz;Robert - FN:Robert Moskowitz - EMAIL;TYPE=INTERNET:rgm-ietf@htt-consult.com - END:VCARD - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Dawson & Stenerson Standards Track [Page 147] - -RFC 2445 iCalendar November 1998 - - -11. Full Copyright Statement - - Copyright (C) The Internet Society (1998). All Rights Reserved. - - This document and translations of it may be copied and furnished to - others, and derivative works that comment on or otherwise explain it - or assist in its implementation may be prepared, copied, published - and distributed, in whole or in part, without restriction of any - kind, provided that the above copyright notice and this paragraph are - included on all such copies and derivative works. However, this - document itself may not be modified in any way, such as by removing - the copyright notice or references to the Internet Society or other - Internet organizations, except as needed for the purpose of - developing Internet standards in which case the procedures for - copyrights defined in the Internet Standards process must be - followed, or as required to translate it into languages other than - English. - - The limited permissions granted above are perpetual and will not be - revoked by the Internet Society or its successors or assigns. - - This document and the information contained herein is provided on an - "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING - TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING - BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION - HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF - MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. - - - - - - - - - - - - - - - - - - - - - - - - -Dawson & Stenerson Standards Track [Page 148] - diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/tests/CMakeLists.txt akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/tests/CMakeLists.txt --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/tests/CMakeLists.txt 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/tests/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,26 +0,0 @@ -project (tests) -cmake_minimum_required(VERSION 2.8) - -if(POLICY CMP0017) - cmake_policy(SET CMP0017 NEW) -endif() - -find_package(Qt4 4.7.0 REQUIRED) - -add_definitions(${QT_DEFINITIONS}) - -include_directories( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/libkgoogle -) - -########### Test Contacts ############### - -set(test_contacts_SRCS - testcontacts.cpp) -kde4_add_executable(test_contacts ${test_contacts_SRCS}) - -target_link_libraries(test_contacts - ${QT_QTCORE_LIBRARY} - ${QT_QTTEST_LIBRARY} - kgoogle) diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/tests/testcontacts.cpp akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/tests/testcontacts.cpp --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/tests/testcontacts.cpp 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/tests/testcontacts.cpp 1970-01-01 00:00:00.000000000 +0000 @@ -1,244 +0,0 @@ -/* - Akonadi Google - Contacts Test - Copyright (C) 2011 Dan Vratil - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - - -#include "kgoogleobject.h" -#include "objects/contact.h" -#include "services/addressbook.h" - -#include -#include -#include -#include - -#include - -using namespace KGoogle; -using namespace KGoogle::Object; -using namespace KGoogle::Service; -using namespace KABC; - -Q_DECLARE_METATYPE(KABC::PhoneNumber::List) -Q_DECLARE_METATYPE(KABC::Address::List) - -class TestContacts : public QObject -{ - Q_OBJECT - -private slots: - void fromJSON_data(); - void fromJSON(); - - void toXML_data(); - void toXML(); - - /* TODO: toJSON() test */ - /* TODO: fromXML() test */ -}; - - -void TestContacts::fromJSON_data() -{ - PhoneNumber::List phoneNumbers; - Address::List addresses; - - QTest::addColumn("jsonData"); - QTest::addColumn("id"); - QTest::addColumn("etag"); - QTest::addColumn("deleted"); - QTest::addColumn("photoUrl"); - QTest::addColumn("name"); - QTest::addColumn("notes"); - QTest::addColumn("job"); - QTest::addColumn("jobTitle"); - QTest::addColumn("birthday"); - //QTest::addColumn("created"); - QTest::addColumn("updated"); - QTest::addColumn("emails"); - //QTest::addColumn("ims"); - QTest::addColumn("phoneNumbers"); - QTest::addColumn("addresses"); - - phoneNumbers << PhoneNumber("+001234567890", PhoneNumber::Cell) - << PhoneNumber("+098765432100", PhoneNumber::Work) - << PhoneNumber("+098123765567", PhoneNumber::Home) - << PhoneNumber("+098765432100", PhoneNumber::Pager); - - Address address(KABC::Address::Home); - address.setStreet("Some Street"); - address.setPostOfficeBox("His POBOX"); - address.setLocality("A Random City"); - address.setRegion("Some state"); - address.setPostalCode("41000"); - address.setCountry("Czech Republic"); - addresses << address; - - address.clear(); - address.setType(KABC::Address::Work); - address.setLabel("Another Street 29\r\nAnother POBOX\r\nAnother City, Some another State 55500\r\nGermany"); - addresses << address; - - QTest::newRow("Contact 1") - << "{\"xmlns\":\"http://www.w3.org/2005/Atom\",\"xmlns$gContact\":\"http://schemas.google.com/contact/2008\",\"xmlns$batch\":\"http://schemas.google.com/gdata/batch\"" - ",\"xmlns$gd\":\"http://schemas.google.com/g/2005\",\"gd$etag\":\"\\\"Q3w_fzVSLit7I2A9WhdSFU4DQwM.\\\"\",\"id\":{\"$t\":\"http://www.google.com/m8/feeds/contacts/some.user%40gmail.com/base/21e062b78964abc6\"}," - "\"updated\":{\"$t\":\"2011-07-24T20:31:12.247Z\"},\"app$edited\":{\"xmlns$app\":\"http://www.w3.org/2007/app\",\"$t\":\"2011-07-24T20:31:12.247Z\"}," - "\"category\":[{\"scheme\":\"http://schemas.google.com/g/2005#kind\",\"term\":\"http://schemas.google.com/contact/2008#contact\"}]," - "\"title\":{\"$t\":\"Mr. FirstName MiddleName Surename CSc.\"},\"content\":{\"$t\":\"Some notes about this nice man.\"},\"link\":[{\"rel\":" - "\"http://schemas.google.com/contacts/2008/rel#photo\",\"type\":\"image/*\",\"href\":\"https://www.google.com/m8/feeds/photos/media/some.user%40gmail.com/21e062b78964abc6\"}," - "{\"rel\":\"self\",\"type\":\"application/atom+xml\",\"href\":\"https://www.google.com/m8/feeds/contacts/some.user%40gmail.com/full/21e062b78964abc6\"},{\"rel\":\"edit\"," - "\"type\":\"application/atom+xml\",\"href\":\"https://www.google.com/m8/feeds/contacts/some.user%40gmail.com/full/21e062b78964abc6\"}],\"gd$name\":{\"gd$fullName\":" - "{\"$t\":\"Mr. FirstName MiddleName Surename CSc.\"},\"gd$namePrefix\":{\"$t\":\"Mr.\"},\"gd$givenName\":{\"$t\":\"FirstName\"},\"gd$additionalName\":{\"$t\":\"MiddleName\"}," - "\"gd$familyName\":{\"$t\":\"Surename\"},\"gd$nameSuffix\":{\"$t\":\"CSc.\"}},\"gContact$nickname\":{\"$t\":\"Johhnie\"},\"gContact$birthday\":{\"when\":\"1991-05-20\"}," - "\"gd$organization\":[{\"rel\":\"http://schemas.google.com/g/2005#other\",\"gd$orgName\":{\"$t\":\"Good Software Inc.\"},\"gd$orgTitle\":{\"$t\":\"Software Engineer\"}}]," - "\"gd$email\":[{\"rel\":\"http://schemas.google.com/g/2005#home\",\"address\":\"email1@server.com\",\"primary\":\"true\"},{\"rel\":\"http://schemas.google.com/g/2005#work\"," - "\"address\":\"email2@server.com\"}],\"gd$im\":[{\"address\":\"jabber@server.com\",\"protocol\":\"http://schemas.google.com/g/2005#JABBER\",\"rel\":" - "\"http://schemas.google.com/g/2005#other\"},{\"address\":\"123456789\",\"protocol\":\"http://schemas.google.com/g/2005#ICQ\",\"rel\":\"http://schemas.google.com/g/2005#other\"}," - "{\"address\":\"talkie@google.com\",\"protocol\":\"http://schemas.google.com/g/2005#GOOGLE_TALK\",\"rel\":\"http://schemas.google.com/g/2005#other\"},{\"address\":\"aim@address.com\"," - "\"protocol\":\"http://schemas.google.com/g/2005#AIM\",\"rel\":\"http://schemas.google.com/g/2005#other\"},{\"address\":\"callme\",\"protocol\":" - "\"http://schemas.google.com/g/2005#SKYPE\",\"rel\":\"http://schemas.google.com/g/2005#other\"}],\"gd$phoneNumber\":[{\"rel\":\"http://schemas.google.com/g/2005#mobile\"," - "\"$t\":\"+001234567890\"},{\"rel\":\"http://schemas.google.com/g/2005#work\",\"$t\":\"+098765432100\"},{\"rel\":\"http://schemas.google.com/g/2005#home\",\"$t\":\"+098123765567\"}," - "{\"rel\":\"http://schemas.google.com/g/2005#pager\",\"$t\":\"+098765432100\"}],\"gd$structuredPostalAddress\":[{\"rel\":\"http://schemas.google.com/g/2005#home\"," - "\"gd$formattedAddress\":{\"$t\":\"Some Street\nHis POBOX\nA Random City, Some state 41000\nCzech Republic\"},\"gd$street\":{\"$t\":\"Some Street\"},\"gd$pobox\":{\"$t\":\"His POBOX\"}," - "\"gd$postcode\":{\"$t\":\"41000\"},\"gd$city\":{\"$t\":\"A Random City\"},\"gd$region\":{\"$t\":\"Some state\"},\"gd$country\":{\"$t\":\"Czech Republic\"}},{\"rel\":" - "\"http://schemas.google.com/g/2005#work\",\"gd$formattedAddress\":{\"$t\":\"Another Street 29\r\nAnother POBOX\r\nAnother City, Some another State 55500\r\nGermany\"}," - "\"gd$street\":{\"$t\":\"Another Street 29\r\nAnother POBOX\r\nAnother City, Some another State 55500\r\nGermany\"}}],\"gContact$groupMembershipInfo\":[{\"deleted\":\"false\"," - "\"href\":\"http://www.google.com/m8/feeds/groups/some.user%40gmail.com/base/6\"}]}" - << "21e062b78964abc6" - << "\"Q3w_fzVSLit7I2A9WhdSFU4DQwM.\"" - << false - << QUrl("https://www.google.com/m8/feeds/photos/media/some.user%40gmail.com/21e062b78964abc6") - << "Mr. FirstName MiddleName Surename CSc." - << "Some notes about this nice man." - << "Good Software Inc." - << "Software Engineer" - << QDateTime::fromString("1991-05-20", "%Y-%m-%d") - //<< KDateTime() - << KDateTime::fromString("2011-07-24T20:31:12.247Z", KDateTime::RFC3339Date) - << (QStringList() << "email1@server.com" << "email2@server.com") - << phoneNumbers - << addresses; -} - - -void TestContacts::fromJSON() -{ - QFETCH(QString, jsonData); - QFETCH(QString, id); - QFETCH(QString, etag); - QFETCH(bool, deleted); - QFETCH(QUrl, photoUrl); - QFETCH(QString, name); - QFETCH(QString, notes); - QFETCH(QString, job); - QFETCH(QString, jobTitle); - QFETCH(QDateTime, birthday); - //QFETCH(KDateTime, created); - QFETCH(KDateTime, updated); - QFETCH(QStringList, emails); - QFETCH(PhoneNumber::List, phoneNumbers); - QFETCH(Address::List, addresses); - - Addressbook *book = new Addressbook(); - Contact *contact = static_cast(book->JSONToObject(jsonData.toLatin1())); - - QCOMPARE(contact->id(), id); - QCOMPARE(contact->etag(), etag); - QCOMPARE(contact->deleted(), deleted); - QCOMPARE(contact->photoUrl(), photoUrl); - QCOMPARE(contact->name(), name); - QCOMPARE(contact->note(), notes); - QCOMPARE(contact->organization(), job); - QCOMPARE(contact->role(), jobTitle); - QCOMPARE(contact->birthday(), birthday); - //QCOMPARE(contact->created().toString(KDateTime::RFC3339Date), created.toString(KDateTime::RFC3339Date)); - QCOMPARE(contact->updated().toString(KDateTime::RFC3339Date), updated.toString(KDateTime::RFC3339Date)); - QCOMPARE(contact->emails(), emails); - QCOMPARE(contact->phoneNumbers(), phoneNumbers); - QCOMPARE(contact->addresses(), addresses); - - delete book; - delete contact; -} - -void TestContacts::toXML_data() -{ - QTest::addColumn("contact"); - QTest::addColumn("xml"); - - Contact::Ptr contact = (Contact::Ptr)new Contact(); - contact->setId("21e062b78964abc6"); - contact->setEtag("\"Q3w_fzVSLit7I2A9WhdSFU4DQwM.\""); - contact->setDeleted(false); - contact->setPhotoUrl(QUrl("https://www.google.com/m8/feeds/photos/media/some.user%40gmail.com/21e062b78964abc6")); - contact->setName("Mr. FirstName MiddleName Surename CSc."); - contact->setNote("Some notes about this nice man."); - contact->setOrganization("Good Software Inc."); - contact->setRole("Software Engineer"); - contact->setBirthday(QDateTime::fromString("1991-05-20", "%Y-%m-%d")); - contact->insertEmail("email1@server.com"); - contact->insertEmail("email2@server.com"); - contact->insertPhoneNumber(PhoneNumber("+001234567890", PhoneNumber::Cell)); - contact->insertPhoneNumber(PhoneNumber("+098765432100", PhoneNumber::Work)); - contact->insertPhoneNumber(PhoneNumber("+098123765567", PhoneNumber::Home)); - contact->insertPhoneNumber(PhoneNumber("+098765432100", PhoneNumber::Pager)); - - Address address; - address.setType(KABC::Address::Home); - address.setStreet("Some Street"); - address.setPostOfficeBox("His POBOX"); - address.setLocality("A Random City"); - address.setRegion("Some state"); - address.setPostalCode("41000"); - address.setCountry("Czech Republic"); - contact->insertAddress(address); - - address.clear(); - address.setType(KABC::Address::Work); - address.setLabel("Another Street 29\r\nAnother POBOX\r\nAnother City, Some another State 55500\r\nGermany"); - contact->insertAddress(address); - - QString xmlData; - - QTest::newRow("Contact 1") - << contact - << "FirstNameCSc.Mr. FirstName MiddleName Surename CSc." - "Some notes about this nice man." - "+001234567890" - "+098765432100+098123765567" - "+098765432100" - "A Random CitySome StreetSome state41000Czech Republic" - "Some Street\nPO BOX His POBOX\nA Random City, Some state 41000\n\nCZECH REPUBLIC" - ""; - -} - -void TestContacts::toXML() -{ - QFETCH(Contact::Ptr, contact); - QFETCH(QString, xml); - - Addressbook *book = new Addressbook(); - KGoogleObject *obj = dynamic_cast(contact.data()); - QByteArray outputXml = book->objectToXML(obj); - - QCOMPARE(QString(outputXml), xml); -} - - -QTEST_MAIN(TestContacts) -#include "testcontacts.moc" diff -Nru akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/TODO akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/TODO --- akonadi-google-0.3.1-0ubuntu1+201205221900-SNAPSHOT/TODO 2012-05-22 19:00:52.000000000 +0000 +++ akonadi-google-0.3.1-0ubuntu1+201206160220-SNAPSHOT/TODO 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ - -TODO -======= - -Feel free to implement any of the tasks below. If you start working -on something, please let me know so that you or someone else would -not waist effort and time by reinventing the wheel. - -libKGoogle ----------- - - complete support for contacts and calendars - - add support for contact groups in Contacts service - - add support for timezones in recurrent events - - - -In some distant future, when Akregator is ported to Akonadi too, I'd -like to have support for Google Feeds