summaryrefslogtreecommitdiffstats
path: root/kresources/caldav/resource.cpp
diff options
context:
space:
mode:
authorTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-01-26 13:17:50 -0600
committerTimothy Pearson <kb9vqf@pearsoncomputing.net>2013-01-26 13:17:50 -0600
commitb363d2579af0a11b77e698aed2e1021c2233b644 (patch)
treef4a47b87354b7a6a3b266c8121bd8ddaeb7accaa /kresources/caldav/resource.cpp
parent61bddfe3a7226b18c68a76124b727c736f431688 (diff)
downloadtdepim-b363d2579af0a11b77e698aed2e1021c2233b644.tar.gz
tdepim-b363d2579af0a11b77e698aed2e1021c2233b644.zip
Rename a number of libraries and executables to avoid conflicts with KDE4
Diffstat (limited to 'kresources/caldav/resource.cpp')
-rw-r--r--kresources/caldav/resource.cpp1011
1 files changed, 0 insertions, 1011 deletions
diff --git a/kresources/caldav/resource.cpp b/kresources/caldav/resource.cpp
deleted file mode 100644
index b9285e611..000000000
--- a/kresources/caldav/resource.cpp
+++ /dev/null
@@ -1,1011 +0,0 @@
-/*=========================================================================
-| KCalDAV
-|--------------------------------------------------------------------------
-| (c) 2010 Timothy Pearson
-| (c) 2009 Kumaran Santhanam (initial KDE4 version)
-|
-| This project is released under the GNU General Public License.
-| Please see the file COPYING for more details.
-|--------------------------------------------------------------------------
-| Main interface to the KResource system.
- ========================================================================*/
-
-/*=========================================================================
-| INCLUDES
- ========================================================================*/
-
-#include <string.h>
-#include <unistd.h>
-
-#include <tqurl.h>
-#include <tqmessagebox.h>
-#include <tqapplication.h>
-#include <tqeventloop.h>
-
-#include <libkcal/calendarlocal.h>
-#include <libkcal/icalformat.h>
-
-#include <klocale.h>
-#include <kpassdlg.h>
-
-#include <tqdatetime.h>
-#include <tqmutex.h>
-#include <tqthread.h>
-
-#ifdef KCALDAV_DEBUG
- #include <tqfile.h>
-#endif
-
-#include "resource.h"
-#include "reader.h"
-#include "writer.h"
-
-/*=========================================================================
-| NAMESPACE
- ========================================================================*/
-
-using namespace KCal;
-
-/*=========================================================================
-| CONSTANTS
- ========================================================================*/
-
-const unsigned long ResourceCalDav::TERMINATION_WAITING_TIME = 3 * 1000; // 3 seconds
-const int ResourceCalDav::CACHE_DAYS = 90;
-
-const int ResourceCalDav::DEFAULT_RELOAD_INTERVAL = 10;
-const int ResourceCalDav::DEFAULT_SAVE_INTERVAL = 10;
-const int ResourceCalDav::DEFAULT_RELOAD_POLICY = ResourceCached::ReloadInterval;
-const int ResourceCalDav::DEFAULT_SAVE_POLICY = ResourceCached::SaveDelayed;
-
-/*=========================================================================
-| UTILITY
- ========================================================================*/
-
-#define log(s) kdDebug() << identifier() << ": " << (s) << '\n';
-
-/*=========================================================================
-| CONSTRUCTOR / DESTRUCTOR
- ========================================================================*/
-
-ResourceCalDav::ResourceCalDav( const TDEConfig *config ) :
- ResourceCached(config)
- , readLockout(false)
- , mAllWritesComplete(false)
- , mLock(true)
- , mPrefs(NULL)
- , mLoader(NULL)
- , mWriter(NULL)
- , mProgress(NULL)
- , mLoadingQueueReady(true)
- , mWritingQueueReady(true)
- , mWriteRetryTimer(NULL)
-{
- log("ResourceCalDav(config)");
- init();
-
- if ( config ) {
- readConfig( config );
- }
-}
-
-ResourceCalDav::~ResourceCalDav() {
- log("jobs termination");
-
- if (mWriteRetryTimer != NULL) {
- mWriteRetryTimer->stop(); // Unfortunately we cannot do anything at this point; if this timer is still running something is seriously wrong
- }
-
- if (mLoader) {
- readLockout = true;
- mLoader->terminate();
- mLoader->wait(TERMINATION_WAITING_TIME);
- mLoadingQueueReady = true;
- }
-
- while ((mWriter->running() == true) || (mWritingQueue.isEmpty() == false) || !mWritingQueueReady) {
- readLockout = true;
- sleep(1);
- tqApp->processEvents(TQEventLoop::ExcludeUserInput);
- }
-
- if (mWriter) {
- mWriter->terminate();
- }
-
- log("waiting for jobs terminated");
-
- if (mLoader) {
- mLoader->wait(TERMINATION_WAITING_TIME);
- }
- if (mWriter) {
- mWriter->wait(TERMINATION_WAITING_TIME);
- }
-
- log("deleting jobs");
-
- delete mLoader;
- delete mWriter;
-
- log("deleting preferences");
-
- delete mPrefs;
-}
-
-bool ResourceCalDav::isSaving() {
- doSave();
- return (((mWriteRetryTimer != NULL) ? 1 : 0) || (mWriter->running() == true) || (mWritingQueue.isEmpty() == false) || !mWritingQueueReady || readLockout);
-}
-
-/*=========================================================================
-| GENERAL METHODS
- ========================================================================*/
-
-bool ResourceCalDav::doLoad() {
- bool syncCache = true;
-
- if ((mLoadingQueueReady == false) || (mLoadingQueue.isEmpty() == false) || (mLoader->running() == true) || (isSaving() == true)) {
- return true; // Silently fail; the user has obviously not responded to a dialog and we don't need to pop up more of them!
- }
-
- log(TQString("doLoad(%1)").arg(syncCache));
-
- clearCache();
-
- log("loading from cache");
- disableChangeNotification();
- loadCache();
- enableChangeNotification();
- clearChanges(); // TODO: Determine if this really needs to be here, as it might clear out the calendar prematurely causing user confusion while the download process is running
- emit resourceChanged(this);
- emit resourceLoaded(this);
-
- log("starting download job");
- startLoading(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl(), mPrefs->getFullJournalsUrl());
-
- return true;
-}
-
-bool ResourceCalDav::doSave() {
- bool syncCache = true;
-
- log(TQString("doSave(%1)").arg(syncCache));
-
- if (!hasChanges()) {
- log("no changes");
- return true;
- }
-
- log("saving cache");
- saveCache();
-
- // Delete any queued read jobs
- mLoadingQueue.clear();
-
- // See if there is a running read thread and terminate it
- if (mLoader->running() == true) {
- mLoader->terminate();
- mLoader->wait(TERMINATION_WAITING_TIME);
- mLoadingQueueReady = true;
- }
-
- log("start writing job");
- if (startWriting(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl(), mPrefs->getFullJournalsUrl()) == true) {
- log("clearing changes");
- // FIXME: Calling clearChanges() here is not the ideal way since the
- // upload might fail, but there is no other place to call it...
- clearChanges();
- if (mWriteRetryTimer != NULL) {
- if (mWriteRetryTimer->isActive() == false) {
- disconnect( mWriteRetryTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(doSave()) );
- delete mWriteRetryTimer;
- mWriteRetryTimer = NULL;
- }
- }
- return true;
- }
- else return true; // We do not need to alert the user to this transient failure; a timer has been started to retry the save
-}
-
-
-KABC::Lock* ResourceCalDav::lock() {
- log("lock()");
- return &mLock;
-}
-
-void ResourceCalDav::readConfig( const TDEConfig *config ) {
- log("readConfig");
- mPrefs->readConfig();
- ResourceCached::readConfig(config);
-}
-
-void ResourceCalDav::writeConfig( TDEConfig *config ) {
- log("writeConfig()");
- ResourceCalendar::writeConfig(config);
- mPrefs->writeConfig();
- ResourceCached::writeConfig(config);
-}
-
-CalDavPrefs* ResourceCalDav::createPrefs() const {
- log("createPrefs()");
- CalDavPrefs* p = new CalDavPrefs(identifier());
- return p;
-}
-
-void ResourceCalDav::init() {
- // default settings
- setReloadInterval(DEFAULT_RELOAD_INTERVAL);
- setReloadPolicy(DEFAULT_RELOAD_POLICY);
- setSaveInterval(DEFAULT_SAVE_INTERVAL);
- setSavePolicy(DEFAULT_SAVE_POLICY);
-
- // creating preferences
- mPrefs = createPrefs();
-
- // creating reader/writer instances
- mLoader = new CalDavReader;
- mWriter = new CalDavWriter;
-
- // creating jobs
- // TQt4 handles this quite differently, as shown below,
- // whereas TQt3 needs events (see ::event())
-// connect(mLoader, TQT_SIGNAL(finished()), this, TQT_SLOT(loadFinished()));
-// connect(mWriter, TQT_SIGNAL(finished()), this, TQT_SLOT(writingFinished()));
-
- setType("ResourceCalDav");
-}
-
-void ResourceCalDav::setIncidencesReadOnly(Incidence::List& inc, bool readOnly) {
- Incidence::List::Iterator it;
- for ( it = inc.begin(); it != inc.end(); ++it ) {
- (*it)->setReadOnly( readOnly );
- }
-}
-
-void ResourceCalDav::ensureReadOnlyFlagHonored() {
- //disableChangeNotification();
-
- Incidence::List inc( rawIncidences() );
- setIncidencesReadOnly(inc, readOnly());
-
- //enableChangeNotification();
-
- emit resourceChanged(this);
-}
-
-void ResourceCalDav::setReadOnly(bool v) {
- KRES::Resource::setReadOnly(v);
- log("ensuring read only flag honored");
- ensureReadOnlyFlagHonored();
-}
-
-void ResourceCalDav::updateProgressBar(int direction) {
- int current_queued_events;
- static int original_queued_events;
-
- // See if anything is in the queues
- current_queued_events = mWritingQueue.count() + mLoadingQueue.count();
- if ((direction == 0) && (mLoader->running() == true)) current_queued_events++;
- if ((direction == 1) && (mWriter->running() == true)) current_queued_events++;
- if (current_queued_events > original_queued_events) {
- original_queued_events = current_queued_events;
- }
-
- if (current_queued_events == 0) {
- if ( mProgress != NULL) {
- mProgress->setComplete();
- mProgress = NULL;
- original_queued_events = 0;
- }
- }
- else {
- if (mProgress == NULL) {
- if (direction == 0) mProgress = KPIM::ProgressManager::createProgressItem(KPIM::ProgressManager::getUniqueID(), i18n("Downloading Calendar") );
- if (direction == 1) mProgress = KPIM::ProgressManager::createProgressItem(KPIM::ProgressManager::getUniqueID(), i18n("Uploading Calendar") );
- }
- mProgress->setProgress( ((((float)original_queued_events-(float)current_queued_events)*100)/(float)original_queued_events) );
- }
-}
-
-/*=========================================================================
-| READING METHODS
- ========================================================================*/
-
-void ResourceCalDav::loadingQueuePush(const LoadingTask *task) {
- if ((mLoadingQueue.isEmpty() == true) && (mLoader->running() == false)) {
- mLoadingQueue.enqueue(task);
- updateProgressBar(0);
- loadingQueuePop();
- }
-}
-
-void ResourceCalDav::loadingQueuePop() {
- if (!mLoadingQueueReady || mLoadingQueue.isEmpty() || (isSaving() == true)) {
- return;
- }
-
- if (!mLoader) {
- log("loader == NULL");
- return;
- }
-
- // Loading queue and mLoadingQueueReady flag are not shared resources, i.e. only one thread has an access to them.
- // That's why no mutexes are required.
- LoadingTask *t = mLoadingQueue.head();
-
- mLoader->setUrl(t->url);
- mLoader->setTasksUrl(t->tasksUrl);
- mLoader->setJournalsUrl(t->journalsUrl);
- mLoader->setParent(this);
- mLoader->setType(0);
-
- TQDateTime dt(TQDate::currentDate());
- mLoader->setRange(dt.addDays(-CACHE_DAYS), dt.addDays(CACHE_DAYS));
- //mLoader->setGetAll();
-
- mLoadingQueueReady = false;
-
- log("starting actual download job");
- mLoader->start(TQThread::LowestPriority);
-
- // if all ok, removing the task from the queue
- mLoadingQueue.dequeue();
- updateProgressBar(0);
-
- delete t;
-}
-
-void ResourceCalDav::startLoading(const TQString& url, const TQString& tasksUrl, const TQString& journalsUrl) {
- LoadingTask *t = new LoadingTask;
- t->url = url;
- t->tasksUrl = tasksUrl;
- t->journalsUrl = journalsUrl;
- loadingQueuePush(t);
-}
-
-void ResourceCalDav::loadFinished() {
- CalDavReader* loader = mLoader;
-
- log("load finished");
-
- if (!loader) {
- log("loader is NULL");
- return;
- }
-
- if (loader->error()) {
- if (loader->errorNumber() == -401) {
- if (NULL != mPrefs) {
- TQCString newpass;
- if (KPasswordDialog::getPassword (newpass, TQString("<b>") + i18n("Remote authorization required") + TQString("</b><p>") + i18n("Please input the password for") + TQString(" ") + mPrefs->getusername(), NULL) != 1) {
- log("load error: " + loader->errorString() );
- loadError(TQString("[%1] ").arg(abs(loader->errorNumber())) + loader->errorString());
- }
- else {
- // Set new password and try again
- mPrefs->setPassword(TQString(newpass));
- startLoading(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl(), mPrefs->getFullJournalsUrl());
- }
- }
- else {
- log("load error: " + loader->errorString() );
- loadError(TQString("[%1] ").arg(abs(loader->errorNumber())) + loader->errorString());
- }
- }
- else {
- log("load error: " + loader->errorString() );
- loadError(TQString("[%1] ").arg(abs(loader->errorNumber())) + loader->errorString());
- }
- } else {
- log("successful event load");
- TQString data = loader->data();
-
- if (!data.isNull() && !data.isEmpty()) {
- // TODO: I don't know why, but some schedules on http://caldav-test.ioda.net/ (I used it for testing)
- // have some lines separated by single \r rather than \n or \r\n.
- // ICalFormat fails to parse that.
- data.replace("\r\n", "\n"); // to avoid \r\n becomes \n\n after the next line
- data.replace('\r', '\n');
-
- log("trying to parse...");
- if (parseData(data)) {
- // FIXME: The agenda view can crash when a change is
- // made on a remote server and a reload is requested!
- log("... parsing is ok");
- log("clearing changes");
- enableChangeNotification();
- clearChanges();
- emit resourceChanged(this);
- emit resourceLoaded(this);
- }
- }
- }
-
- if (loader->tasksError()) {
- if (loader->tasksErrorNumber() == -401) {
- if (NULL != mPrefs) {
-// TQCString newpass;
-// if (KPasswordDialog::getPassword (newpass, TQString("<b>") + i18n("Remote authorization required") + TQString("</b><p>") + i18n("Please input the password for") + TQString(" ") + mPrefs->getusername(), NULL) != 1) {
-// log("load error: " + loader->tasksErrorString() );
-// loadError(TQString("[%1] ").arg(abs(loader->tasksErrorNumber())) + loader->tasksErrorString());
-// }
-// else {
-// // Set new password and try again
-// mPrefs->setPassword(TQString(newpass));
-// startLoading(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl(), mPrefs->getFullJournalsUrl());
-// }
- }
- else {
- log("load error: " + loader->tasksErrorString() );
- loadError(TQString("[%1] ").arg(abs(loader->tasksErrorNumber())) + loader->tasksErrorString());
- }
- }
- else {
- log("load error: " + loader->tasksErrorString() );
- loadError(TQString("[%1] ").arg(abs(loader->tasksErrorNumber())) + loader->tasksErrorString());
- }
- } else {
- log("successful tasks load");
- TQString tasksData = loader->tasksData();
-
- if (!tasksData.isNull() && !tasksData.isEmpty()) {
- // TODO: I don't know why, but some schedules on http://caldav-test.ioda.net/ (I used it for testing)
- // have some lines separated by single \r rather than \n or \r\n.
- // ICalFormat fails to parse that.
- tasksData.replace("\r\n", "\n"); // to avoid \r\n becomes \n\n after the next line
- tasksData.replace('\r', '\n');
-
- log("trying to parse...");
- if (parseTasksData(tasksData)) {
- // FIXME: The agenda view can crash when a change is
- // made on a remote server and a reload is requested!
- log("... parsing is ok");
- log("clearing changes");
- enableChangeNotification();
- clearChanges();
- emit resourceChanged(this);
- emit resourceLoaded(this);
- }
- }
- }
-
- if (loader->journalsError()) {
- if (loader->journalsErrorNumber() == -401) {
- if (NULL != mPrefs) {
-// TQCString newpass;
-// if (KPasswordDialog::getPassword (newpass, TQString("<b>") + i18n("Remote authorization required") + TQString("</b><p>") + i18n("Please input the password for") + TQString(" ") + mPrefs->getusername(), NULL) != 1) {
-// log("load error: " + loader->journalsErrorString() );
-// loadError(TQString("[%1] ").arg(abs(loader->journalsErrorNumber())) + loader->journalsErrorString());
-// }
-// else {
-// // Set new password and try again
-// mPrefs->setPassword(TQString(newpass));
-// startLoading(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl(), mPrefs->getFullJournalsUrl());
-// }
- }
- else {
- log("load error: " + loader->journalsErrorString() );
- loadError(TQString("[%1] ").arg(abs(loader->journalsErrorNumber())) + loader->journalsErrorString());
- }
- }
- else {
- log("load error: " + loader->journalsErrorString() );
- loadError(TQString("[%1] ").arg(abs(loader->journalsErrorNumber())) + loader->journalsErrorString());
- }
- } else {
- log("successful journals load");
- TQString journalsData = loader->journalsData();
-
- if (!journalsData.isNull() && !journalsData.isEmpty()) {
- // TODO: I don't know why, but some schedules on http://caldav-test.ioda.net/ (I used it for testing)
- // have some lines separated by single \r rather than \n or \r\n.
- // ICalFormat fails to parse that.
- journalsData.replace("\r\n", "\n"); // to avoid \r\n becomes \n\n after the next line
- journalsData.replace('\r', '\n');
-
- log("trying to parse...");
- if (parseJournalsData(journalsData)) {
- // FIXME: The agenda view can crash when a change is
- // made on a remote server and a reload is requested!
- log("... parsing is ok");
- log("clearing changes");
- enableChangeNotification();
- clearChanges();
- emit resourceChanged(this);
- emit resourceLoaded(this);
- }
- }
- }
-
- // Loading queue and mLoadingQueueReady flag are not shared resources, i.e. only one thread has an access to them.
- // That's why no mutexes are required.
- mLoader->terminate();
- mLoader->wait(TERMINATION_WAITING_TIME);
- mLoadingQueueReady = true;
- updateProgressBar(0);
- loadingQueuePop();
-}
-
-bool ResourceCalDav::checkData(const TQString& data) {
- log("checking the data");
-
- ICalFormat ical;
- bool ret = true;
- if (!ical.fromString(&mCalendar, data)) {
- log("invalid ical string");
- ret = false;
- }
-
- return ret;
-}
-
-bool ResourceCalDav::parseData(const TQString& data) {
- log("parseData()");
-
- bool ret = true;
-
- // check if the data is OK
- // May be it's not efficient (parsing is done twice), but it should be safe
- if (!checkData(data)) {
- loadError(i18n("Parsing calendar data failed."));
- return false;
- }
-
- log("clearing cache");
- clearEventsCache();
-
- disableChangeNotification();
-
- log("actually parsing the data");
-
- ICalFormat ical;
- if ( !ical.fromString( &mCalendar, data ) ) {
- // this should never happen, but...
- ret = false;
- }
-
- // debug code here -------------------------------------------------------
-#ifdef KCALDAV_DEBUG
- const TQString fout_path = "/tmp/kcaldav_download_" + identifier() + ".tmp";
-
- TQFile fout(fout_path);
- if (fout.open(IO_WriteOnly | IO_Append)) {
- TQTextStream sout(&fout);
- sout << "---------- " << resourceName() << ": --------------------------------\n";
- sout << data << "\n";
- fout.close();
- } else {
- loadError(i18n("can't open file"));
- }
-#endif // KCALDAV_DEBUG
- // end of debug code ----------------------------------------------------
-
- enableChangeNotification();
-
- if (ret) {
- log("parsing is ok");
- //if ( !noReadOnlyOnLoad() && readOnly() ) {
- if ( readOnly() ) {
- log("ensuring read only flag honored");
- ensureReadOnlyFlagHonored();
- }
- log("saving to cache");
- saveCache();
- }
-
- return ret;
-}
-
-bool ResourceCalDav::parseTasksData(const TQString& data) {
- log("parseTasksData()");
-
- bool ret = true;
-
- // check if the data is OK
- // May be it's not efficient (parsing is done twice), but it should be safe
- if (!checkData(data)) {
- loadError(i18n("Parsing calendar data failed."));
- return false;
- }
-
- log("clearing cache");
- clearTodosCache();
-
- disableChangeNotification();
-
- log("actually parsing the data");
-
- ICalFormat ical;
- if ( !ical.fromString( &mCalendar, data ) ) {
- // this should never happen, but...
- ret = false;
- }
-
- // debug code here -------------------------------------------------------
-#ifdef KCALDAV_DEBUG
- const TQString fout_path = "/tmp/kcaldav_download_" + identifier() + ".tmp";
-
- TQFile fout(fout_path);
- if (fout.open(IO_WriteOnly | IO_Append)) {
- TQTextStream sout(&fout);
- sout << "---------- " << resourceName() << ": --------------------------------\n";
- sout << data << "\n";
- fout.close();
- } else {
- loadError(i18n("can't open file"));
- }
-#endif // KCALDAV_DEBUG
- // end of debug code ----------------------------------------------------
-
- enableChangeNotification();
-
- if (ret) {
- log("parsing is ok");
- //if ( !noReadOnlyOnLoad() && readOnly() ) {
- if ( readOnly() ) {
- log("ensuring read only flag honored");
- ensureReadOnlyFlagHonored();
- }
- log("saving to cache");
- saveCache();
- }
-
- return ret;
-}
-
-bool ResourceCalDav::parseJournalsData(const TQString& data) {
- log("parseJournalsData()");
-
- bool ret = true;
-
- // check if the data is OK
- // May be it's not efficient (parsing is done twice), but it should be safe
- if (!checkData(data)) {
- loadError(i18n("Parsing calendar data failed."));
- return false;
- }
-
- log("clearing cache");
- clearJournalsCache();
-
- disableChangeNotification();
-
- log("actually parsing the data");
-
- ICalFormat ical;
- if ( !ical.fromString( &mCalendar, data ) ) {
- // this should never happen, but...
- ret = false;
- }
-
- // debug code here -------------------------------------------------------
-#ifdef KCALDAV_DEBUG
- const TQString fout_path = "/tmp/kcaldav_download_" + identifier() + ".tmp";
-
- TQFile fout(fout_path);
- if (fout.open(IO_WriteOnly | IO_Append)) {
- TQTextStream sout(&fout);
- sout << "---------- " << resourceName() << ": --------------------------------\n";
- sout << data << "\n";
- fout.close();
- } else {
- loadError(i18n("can't open file"));
- }
-#endif // KCALDAV_DEBUG
- // end of debug code ----------------------------------------------------
-
- enableChangeNotification();
-
- if (ret) {
- log("parsing is ok");
- //if ( !noReadOnlyOnLoad() && readOnly() ) {
- if ( readOnly() ) {
- log("ensuring read only flag honored");
- ensureReadOnlyFlagHonored();
- }
- log("saving to cache");
- saveCache();
- }
-
- return ret;
-}
-
-/*=========================================================================
-| WRITING METHODS
- ========================================================================*/
-
-TQString ResourceCalDav::getICalString(const Incidence::List& inc) {
- if (inc.isEmpty()) {
- return "";
- }
-
- CalendarLocal loc(timeZoneId());
- TQString data = "";
- TQString header = "";
- TQString footer = "";
- ICalFormat ical;
-
- // Get the iCal header and footer
- header = ical.toString(&loc);
- int location = header.find("END:VCALENDAR", 0, true);
- footer = header.mid(location, 0xffffffff);
- header.remove("END:VCALENDAR");
-
- data = data + header;
- // NOTE: This is very susceptible to invalid entries in added/changed/deletedIncidences
- // Be very careful with clearChange/clearChanges, and be sure to clear after load and save...
- for(Incidence::List::ConstIterator it = inc.constBegin(); it != inc.constEnd(); ++it) {
- Incidence *i = (*it)->clone();
- data = data + ical.toString(i, &mCalendar);
- }
- data = data + footer;
-
- // Remove any line feeds/carriage returns/white spaces from the UID field as they WILL break libcaldav
- int uidPos = data.find("UID:", 0) + 4;
- int nextPos = data.findRev("\n", data.find(":", uidPos));
- TQString uidField = data.mid(uidPos, nextPos-uidPos);
- data.remove(uidPos, nextPos-uidPos);
- uidField.replace("\n", "");
- uidField.replace("\r", "");
- uidField.replace(" ", "");
- data.insert(uidPos, uidField);
- return data;
-}
-
-void ResourceCalDav::writingQueuePush(const WritingTask *task) {
-// printf("task->added: %s\n\r", task->added.ascii());
-// printf("task->deleted: %s\n\r", task->deleted.ascii());
-// printf("task->changed: %s\n\r", task->changed.ascii());
- mWritingQueue.enqueue(task);
- updateProgressBar(1);
- writingQueuePop();
-}
-
-void ResourceCalDav::writingQueuePop() {
- if (!mWritingQueueReady || mWritingQueue.isEmpty()) {
- return;
- }
-
- if (!mWriter) {
- log("writer == NULL");
- return;
- }
-
- // Writing queue and mWritingQueueReady flag are not shared resources, i.e. only one thread has an access to them.
- // That's why no mutexes are required.
- WritingTask *t = mWritingQueue.head();
-
- log("writingQueuePop: url = " + t->url);
-
- mWriter->setUrl(t->url);
- mWriter->setTasksUrl(t->tasksUrl);
- mWriter->setJournalsUrl(t->journalsUrl);
- mWriter->setParent(this);
- mWriter->setType(1);
-
-#ifdef KCALDAV_DEBUG
- const TQString fout_path = "/tmp/kcaldav_upload_" + identifier() + ".tmp";
-
- TQFile fout(fout_path);
- if (fout.open(IO_WriteOnly | IO_Append)) {
- TQTextStream sout(&fout);
- sout << "---------- " << resourceName() << ": --------------------------------\n";
- sout << "================== Added:\n" << t->added << "\n";
- sout << "================== Changed:\n" << t->changed << "\n";
- sout << "================== Deleted:\n" << t->deleted << "\n";
- fout.close();
- } else {
- loadError(i18n("can't open file"));
- }
-#endif // debug
-
- mWriter->setAddedObjects(t->added);
- mWriter->setChangedObjects(t->changed);
- mWriter->setDeletedObjects(t->deleted);
-
- mWriter->setAddedTasksObjects(t->tasksAdded);
- mWriter->setChangedTasksObjects(t->tasksChanged);
- mWriter->setDeletedTasksObjects(t->tasksDeleted);
-
- mWriter->setAddedJournalsObjects(t->journalsAdded);
- mWriter->setChangedJournalsObjects(t->journalsChanged);
- mWriter->setDeletedJournalsObjects(t->journalsDeleted);
-
- mWritingQueueReady = false;
-
- log("starting actual write job");
- mWriter->start(TQThread::LowestPriority);
-
- // if all ok, remove the task from the queue
- mWritingQueue.dequeue();
- updateProgressBar(1);
-
- delete t;
-}
-
-bool ResourceCalDav::event ( TQEvent * e ) {
- if (e->type() == 1000) {
- // Read done
- loadFinished();
- return TRUE;
- }
- else if (e->type() == 1001) {
- // Write done
- writingFinished();
- return TRUE;
- }
- else return FALSE;
-}
-
-void ResourceCalDav::releaseReadLockout() {
- readLockout = false;
-}
-
-bool ResourceCalDav::startWriting(const TQString& url, const TQString& tasksUrl, const TQString& journalsUrl) {
- log("startWriting: url = " + url);
-
- // WARNING: This will segfault if a separate read or write thread
- // modifies the calendar with clearChanges() or similar
- // Before these calls are made any existing read (and maybe write) threads should be finished
- if ((mLoader->running() == true) || (mLoadingQueue.isEmpty() == false) || (mWriter->running() == true) || (mWritingQueue.isEmpty() == false)) {
- if (mWriteRetryTimer == NULL) {
- mWriteRetryTimer = new TQTimer(this);
- connect( mWriteRetryTimer, TQT_SIGNAL(timeout()), TQT_SLOT(doSave()) );
- }
- mWriteRetryTimer->start(1000, TRUE);
- return false;
- }
-
- // If we don't lock the read out for a few seconds, it would be possible for the old calendar to be
- // downloaded before our changes are committed, presenting a very bad image to the user as his/her appointments
- // revert to the state they were in before the write (albiet temporarily)
- readLockout = true;
-
- // This needs to send each event separately; i.e. if two events were added they need
- // to be extracted and pushed on the stack independently (using two calls to writingQueuePush())
-
- Incidence::List added = addedIncidences();
- Incidence::List changed = changedIncidences();
- Incidence::List deleted = deletedIncidences();
-
- Incidence::List::ConstIterator it;
- Incidence::List currentIncidence;
-
- for( it = added.begin(); it != added.end(); ++it ) {
- WritingTask *t = new WritingTask;
-
- currentIncidence.clear();
- currentIncidence.append(*it);
-
- t->url = url;
- t->tasksUrl = tasksUrl;
- t->journalsUrl = journalsUrl;
- t->added = "";
- t->changed = "";
- t->deleted = "";
- t->tasksAdded = "";
- t->tasksChanged = "";
- t->tasksDeleted = "";
- t->journalsAdded = "";
- t->journalsChanged = "";
- t->journalsDeleted = "";
- if (getICalString(currentIncidence).contains("BEGIN:VEVENT") > 0)
- t->added = getICalString(currentIncidence);
- else if (getICalString(currentIncidence).contains("BEGIN:VTODO") > 0)
- t->tasksAdded = getICalString(currentIncidence);
- else if (getICalString(currentIncidence).contains("BEGIN:VJOURNAL") > 0)
- t->journalsAdded = getICalString(currentIncidence);
-
- writingQueuePush(t);
- }
-
- for( it = changed.begin(); it != changed.end(); ++it ) {
- WritingTask *t = new WritingTask;
-
- currentIncidence.clear();
- currentIncidence.append(*it);
-
- t->url = url;
- t->tasksUrl = tasksUrl;
- t->added = "";
- t->changed = "";
- t->deleted = "";
- t->tasksAdded = "";
- t->tasksChanged = "";
- t->tasksDeleted = "";
- t->journalsAdded = "";
- t->journalsChanged = "";
- t->journalsDeleted = "";
-
- if (getICalString(currentIncidence).contains("BEGIN:VEVENT") > 0)
- t->changed = getICalString(currentIncidence);
- else if (getICalString(currentIncidence).contains("BEGIN:VTODO") > 0)
- t->tasksChanged = getICalString(currentIncidence);
- else if (getICalString(currentIncidence).contains("BEGIN:VJOURNAL") > 0)
- t->journalsChanged = getICalString(currentIncidence);
-
- writingQueuePush(t);
- }
-
- for( it = deleted.begin(); it != deleted.end(); ++it ) {
- WritingTask *t = new WritingTask;
-
- currentIncidence.clear();
- currentIncidence.append(*it);
-
- t->url = url;
- t->tasksUrl = tasksUrl;
- t->added = "";
- t->changed = "";
- t->deleted = "";
- t->tasksAdded = "";
- t->tasksChanged = "";
- t->tasksDeleted = "";
- t->journalsAdded = "";
- t->journalsChanged = "";
- t->journalsDeleted = "";
-
- if (getICalString(currentIncidence).contains("BEGIN:VEVENT") > 0)
- t->deleted = getICalString(currentIncidence);
- else if (getICalString(currentIncidence).contains("BEGIN:VTODO") > 0)
- t->tasksDeleted = getICalString(currentIncidence);
- else if (getICalString(currentIncidence).contains("BEGIN:VJOURNALS") > 0)
- t->journalsDeleted = getICalString(currentIncidence);
-
- writingQueuePush(t);
- }
-
- return true;
-}
-
-void ResourceCalDav::writingFinished() {
- log("writing finished");
-
- if (!mWriter) {
- log("mWriter is NULL");
- return;
- }
-
- if (mWriter->error() && (abs(mWriter->errorNumber()) != 207)) {
- if (mWriter->errorNumber() == -401) {
- if (NULL != mPrefs) {
- TQCString newpass;
- if (KPasswordDialog::getPassword (newpass, TQString("<b>") + i18n("Remote authorization required") + TQString("</b><p>") + i18n("Please input the password for") + TQString(" ") + mPrefs->getusername(), NULL) != 1) {
- log("write error: " + mWriter->errorString());
- saveError(TQString("[%1] ").arg(abs(mWriter->errorNumber())) + mWriter->errorString());
- }
- else {
- // Set new password and try again
- mPrefs->setPassword(TQString(newpass));
- startWriting(mPrefs->getFullUrl(), mPrefs->getFullTasksUrl(), mPrefs->getFullJournalsUrl());
- }
- }
- else {
- log("write error: " + mWriter->errorString());
- saveError(TQString("[%1] ").arg(abs(mWriter->errorNumber())) + mWriter->errorString());
- }
- }
- else {
- log("write error: " + mWriter->errorString());
- saveError(TQString("[%1] ").arg(abs(mWriter->errorNumber())) + mWriter->errorString());
- }
- } else {
- log("success");
- // is there something to do here?
- }
-
- // Give the remote system a few seconds to process the data before we allow any read operations
- TQTimer::singleShot( 3000, this, TQT_SLOT(releaseReadLockout()) );
-
- // Writing queue and mWritingQueueReady flag are not shared resources, i.e. only one thread has an access to them.
- // That's why no mutexes are required.
- mWriter->terminate();
- mWriter->wait(TERMINATION_WAITING_TIME);
- mWritingQueueReady = true;
- updateProgressBar(1);
- writingQueuePop();
-}
-
-#include "resource.moc"
-
-// EOF ========================================================================