bool NemoCalendarImportModel::importFromFile(const QString &fileName, KCalCore::Calendar::Ptr calendar) { QString filePath; QUrl url(fileName); if (url.isLocalFile()) filePath = url.toLocalFile(); else filePath = fileName; if (!(filePath.endsWith(".vcs") || filePath.endsWith(".ics"))) { qWarning() << "Unsupported file format" << filePath; return false; } QFile file(filePath); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() << "Unable to open file for reading" << filePath; return false; } QString fileContent(file.readAll()); bool ok = false; if (filePath.endsWith(".vcs")) { KCalCore::VCalFormat vcalFormat; ok = vcalFormat.fromString(calendar, fileContent); } else if (filePath.endsWith(".ics")) { KCalCore::ICalFormat icalFormat; ok = icalFormat.fromString(calendar, fileContent); } if (!ok) qWarning() << "Failed to import from file" << filePath; return ok; }
bool NotebookSyncAgent::discardRemoteChanges(KCalCore::Incidence::List *localInserted, KCalCore::Incidence::List *localModified, KCalCore::Incidence::List *localDeleted) { NOTEBOOK_FUNCTION_CALL_TRACE; // Go through the local inserted, modified and deletions list and: // - Discard from them respectively the additions, modifications and deletions that were // created as a result of the last remote sync. // - Discard any incidences that have already been deleted on the server. (These will be // deleted locally when the current sync finishes.) // - Discard any local modifications that were modified on the server, as the server // modifications take precedence. if (!mNotebook) { LOG_CRITICAL("no notebook"); return false; } bool ok = false; QSet<QString> remoteDeletedIncidences = QSet<QString>::fromList(mIncidenceUidsToDelete); QStringList additions = mDatabase->additions(mNotebook->uid(), &ok); if (!ok) { LOG_CRITICAL("Unable to look up last sync additions for notebook:" << mNotebook->uid()); return false; } QHash<QString,QString> modifications = mDatabase->modifications(mNotebook->uid(), &ok); if (!ok) { LOG_CRITICAL("Unable to look up last sync modifications for notebook:" << mNotebook->uid()); return false; } for (KCalCore::Incidence::List::iterator it = localInserted->begin(); it != localInserted->end();) { const KCalCore::Incidence::Ptr &incidence = *it; const QString &uid = incidence->uid(); if (remoteDeletedIncidences.contains(uid)) { LOG_DEBUG("Discarding addition deleted on server:" << uid); it = localInserted->erase(it); } else if (additions.indexOf(uid) >= 0) { if (incidence->lastModified().isValid() && incidence->lastModified() > incidence->created()) { // This incidence has been modified since it was added from the server in the last sync, // so it's a modification rather than an addition. LOG_DEBUG("Moving to modified:" << uid); KCalCore::Incidence::Ptr savedIncidence = fetchIncidence(mCalendar, uid); if (savedIncidence) { localModified->append(savedIncidence); it = localInserted->erase(it); } else { ++it; } } else { LOG_DEBUG("Discarding addition from previous sync:" << uid); it = localInserted->erase(it); } } else { ++it; } } QSet<QString> serverModifiedUids; for (int i=0; i<mReceivedCalendarResources.count(); i++) { serverModifiedUids.insert(Reader::hrefToUid(mReceivedCalendarResources[i].href)); } for (KCalCore::Incidence::List::iterator it = localModified->begin(); it != localModified->end();) { KCalCore::Incidence::Ptr sourceIncidence = *it; const QString &uid = sourceIncidence->uid(); if (remoteDeletedIncidences.contains(uid) || serverModifiedUids.contains(uid)) { LOG_DEBUG("Discarding modification," << (remoteDeletedIncidences.contains(uid) ? "was already deleted on server" : "") << (serverModifiedUids.contains(uid) ? "was already modified on server": "")); it = localModified->erase(it); continue; } else if (modifications.contains(uid)) { KCalCore::ICalFormat iCalFormat; KCalCore::Incidence::Ptr receivedIncidence = iCalFormat.fromString(modifications[uid]); if (receivedIncidence.isNull()) { LOG_WARNING("Not sending modification, cannot parse the received incidence:" << modifications[uid]); it = localModified->erase(it); continue; } // If incidences are the same, then we assume the local incidence was not changed after // the remote incidence was received, and thus there are no modifications to report. IncidenceHandler::prepareImportedIncidence(receivedIncidence); // ensure fields are updated as per imported incidences if (IncidenceHandler::copiedPropertiesAreEqual(sourceIncidence, receivedIncidence)) { LOG_DEBUG("Discarding modification" << uid); it = localModified->erase(it); continue; } } // The default storage implementation applies the organizer as an attendee by default. Don't do this // as it turns the incidence into a scheduled event requiring acceptance/rejection/etc. const KCalCore::Person::Ptr organizer = sourceIncidence->organizer(); if (organizer) { Q_FOREACH (const KCalCore::Attendee::Ptr &attendee, sourceIncidence->attendees()) { if (attendee->email() == organizer->email() && attendee->fullName() == organizer->fullName()) { LOG_DEBUG("Discarding organizer as attendee" << attendee->fullName()); sourceIncidence->deleteAttendee(attendee); break; } } } ++it; } QStringList deletions = mDatabase->deletions(mNotebook->uid(), &ok); if (!ok) { LOG_CRITICAL("Unable to look up last sync deletions for notebook:" << mNotebook->uid()); return false; } for (KCalCore::Incidence::List::iterator it = localDeleted->begin(); it != localDeleted->end();) { const QString &uid = (*it)->uid(); mLocalDeletedUids.insert(uid); if (remoteDeletedIncidences.contains(uid) || deletions.indexOf(uid) >= 0) { LOG_DEBUG("Discarding deletion" << uid); it = localDeleted->erase(it); } else { ++it; } } return true; }