• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.14.10 API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • akonadi
  • calendar
icalimporter.cpp
1
22#include "icalimporter.h"
23#include "icalimporter_p.h"
24#include "utils_p.h"
25
26#include <akonadi/agentmanager.h>
27#include <akonadi/agentinstancecreatejob.h>
28
29#include <kcalcore/filestorage.h>
30#include <kcalcore/memorycalendar.h>
31#include <kcalcore/event.h>
32#include <kcalcore/todo.h>
33#include <kcalcore/journal.h>
34
35#include <KJob>
36#include <KLocalizedString>
37#include <KDebug>
38#include <KDateTime>
39#include <KUrl>
40#include <KIO/JobClasses>
41#include <KIO/Scheduler>
42#include <KTemporaryFile>
43
44#include <QUrl>
45#include <QFile>
46#include <QDBusInterface>
47
48using namespace KCalCore;
49using namespace Akonadi;
50
51ICalImporter::Private::Private(IncidenceChanger *changer,
52 ICalImporter *qq) : QObject(), q(qq)
53 , m_changer(changer)
54 , m_numIncidences(0)
55 , m_working(false)
56 , m_temporaryFile(0)
57{
58 if (!changer) {
59 m_changer = new IncidenceChanger(q);
60 }
61 connect(m_changer, SIGNAL(createFinished(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)),
62 SLOT(onIncidenceCreated(int,Akonadi::Item,Akonadi::IncidenceChanger::ResultCode,QString)));
63
64}
65
66ICalImporter::Private::~Private()
67{
68 delete m_temporaryFile;
69}
70
71void ICalImporter::Private::onIncidenceCreated(int changeId,
72 const Akonadi::Item &,
73 Akonadi::IncidenceChanger::ResultCode resultCode,
74 const QString &errorString)
75{
76 if (!m_pendingRequests.contains(changeId))
77 return; // Not ours
78
79 m_pendingRequests.removeAll(changeId);
80
81 if (resultCode != IncidenceChanger::ResultCodeSuccess) {
82 m_working = false;
83 setErrorMessage(errorString);
84 m_pendingRequests.clear();
85 emit q->importIntoExistingFinished(false, m_numIncidences);
86 } else if (m_pendingRequests.isEmpty()) {
87 m_working = false;
88 emit q->importIntoExistingFinished(true, m_numIncidences);
89 }
90}
91
92void ICalImporter::Private::setErrorMessage(const QString &message)
93{
94 m_lastErrorMessage = message;
95 kError() << message;
96}
97
98void ICalImporter::Private::resourceCreated(KJob *job)
99{
100 Akonadi::AgentInstanceCreateJob *createjob = qobject_cast<Akonadi::AgentInstanceCreateJob*>(job);
101 Q_ASSERT(createjob);
102 m_working = false;
103 if (createjob->error()) {
104 setErrorMessage(i18n("Error creating ical resource: %1", createjob->errorString()));
105 emit q->importIntoNewFinished(false);
106 return;
107 }
108
109 Akonadi::AgentInstance instance = createjob->instance();
110 QDBusInterface iface(QString::fromLatin1("org.freedesktop.Akonadi.Resource.%1").arg(instance.identifier()), QLatin1String("/Settings"));
111
112 if (!iface.isValid()) {
113 setErrorMessage(i18n("Failed to obtain D-Bus interface for remote configuration."));
114 emit q->importIntoNewFinished(false);
115 return;
116 }
117
118 const QString path = createjob->property("path").toString();
119 Q_ASSERT(!path.isEmpty());
120
121 iface.call(QLatin1String("setPath"), path);
122 instance.reconfigure();
123
124 emit q->importIntoNewFinished(true);
125}
126
127void ICalImporter::Private::remoteDownloadFinished(KIO::Job *job, const QByteArray &data)
128{
129 const bool success = job->error() == 0;
130 m_working = false;
131 if (success) {
132 delete m_temporaryFile;
133 m_temporaryFile = new KTemporaryFile();
134 m_temporaryFile->write(data.constData(), data.count());
135 q->importIntoExistingResource(QUrl(m_temporaryFile->fileName()), m_collection);
136 } else {
137 setErrorMessage(i18n("Could not download remote file."));
138 emit q->importIntoExistingFinished(false, 0);
139 }
140}
141
142ICalImporter::ICalImporter(Akonadi::IncidenceChanger *changer,
143 QObject *parent) : QObject(parent)
144 , d(new Private(changer, this))
145{
146}
147
148QString ICalImporter::errorMessage() const
149{
150 return d->m_lastErrorMessage;
151}
152
153bool ICalImporter::importIntoNewResource(const QString &filename)
154{
155 d->m_lastErrorMessage.clear();
156
157 if (d->m_working) {
158 d->setErrorMessage(i18n("An import task is already in progress."));
159 return false;
160 }
161
162 d->m_working = true;
163
164 Akonadi::AgentType type = Akonadi::AgentManager::self()->type(QLatin1String("akonadi_ical_resource"));
165 Akonadi::AgentInstanceCreateJob *job = new Akonadi::AgentInstanceCreateJob(type, this);
166 job->setProperty("path", filename);
167 connect(job, SIGNAL(result(KJob*)), d, SLOT(resourceCreated(KJob*)));
168 job->start();
169
170 return true;
171}
172
173bool ICalImporter::importIntoExistingResource(const QUrl &url, Akonadi::Collection collection)
174{
175 d->m_lastErrorMessage.clear();
176
177 if (d->m_working) {
178 d->setErrorMessage(i18n("An import task is already in progress."));
179 return false;
180 }
181
182 if (url.isEmpty()) {
183 d->setErrorMessage(i18n("Empty filename. Will not import ical file."));
184 return false;
185 }
186
187 if (!url.isValid()) {
188 d->setErrorMessage(i18n("Url to import is malformed."));
189 return false;
190 }
191
192 if (url.isLocalFile()) {
193 if (!QFile::exists(url.path())) {
194 d->setErrorMessage(i18n("The specified file doesn't exist, aborting import."));
195 return false;
196 }
197 MemoryCalendar::Ptr temporaryCalendar(new MemoryCalendar(KDateTime::LocalZone));
198 FileStorage storage(temporaryCalendar);
199 storage.setFileName(url.path());
200 bool success = storage.load();
201 if (!success) {
202 d->setErrorMessage(i18n("Failed to load ical file, check permissions."));
203 return false;
204 }
205
206 d->m_pendingRequests.clear();
207 Incidence::List incidences = temporaryCalendar->incidences();
208
209 if (incidences.isEmpty()) {
210 d->setErrorMessage(i18n("The ical file to merge is empty."));
211 return false;
212 }
213
214 if (!collection.isValid()) {
215 int dialogCode;
216 QStringList mimeTypes = QStringList() << KCalCore::Event::eventMimeType() << KCalCore::Todo::todoMimeType()
217 << KCalCore::Journal::journalMimeType();
218 collection = CalendarUtils::selectCollection(0, dialogCode /*by-ref*/, mimeTypes);
219 }
220
221 if (!collection.isValid()) {
222 // user canceled
223 d->setErrorMessage(QString());
224 return false;
225 }
226
227 const IncidenceChanger::DestinationPolicy policySaved = d->m_changer->destinationPolicy();
228 d->m_changer->startAtomicOperation(i18n("Merge ical file into existing calendar."));
229 d->m_changer->setDestinationPolicy(IncidenceChanger::DestinationPolicyNeverAsk);
230 foreach(const Incidence::Ptr &incidence, incidences) {
231 Q_ASSERT(incidence);
232 if (!incidence)
233 continue;
234 const int requestId = d->m_changer->createIncidence(incidence, collection);
235 Q_ASSERT(requestId != -1); // -1 only happens with invalid incidences
236 if (requestId != -1)
237 d->m_pendingRequests << requestId;
238 }
239 d->m_changer->endAtomicOperation();
240
241 d->m_changer->setDestinationPolicy(policySaved); // restore
242 d->m_numIncidences = incidences.count();
243 } else {
244 d->m_collection = collection;
245 KIO::StoredTransferJob *job = KIO::storedGet(KUrl(url));
246 connect(job, SIGNAL(data(KIO::Job*,QByteArray)), d, SLOT(remoteDownloadFinished(KIO::Job*,QByteArray)));
247 }
248
249 d->m_working = true;
250 return true;
251}
Akonadi::AgentInstanceCreateJob
Job for creating new agent instances.
Definition: agentinstancecreatejob.h:72
Akonadi::AgentInstanceCreateJob::start
void start()
Starts the instance creation.
Definition: agentinstancecreatejob.cpp:176
Akonadi::AgentInstanceCreateJob::instance
AgentInstance instance() const
Returns the AgentInstance object of the newly created agent instance.
Definition: agentinstancecreatejob.cpp:171
Akonadi::AgentInstance
A representation of an agent instance.
Definition: agentinstance.h:63
Akonadi::AgentInstance::identifier
QString identifier() const
Returns the unique identifier of the agent instance.
Definition: agentinstance.cpp:55
Akonadi::AgentInstance::reconfigure
void reconfigure() const
Tell the agent that its configuration has been changed remotely via D-Bus.
Definition: agentinstance.cpp:149
Akonadi::AgentManager::type
AgentType type(const QString &identifier) const
Returns the agent type with the given identifier or an invalid agent type if the identifier does not ...
Definition: agentmanager.cpp:391
Akonadi::AgentManager::self
static AgentManager * self()
Returns the global instance of the agent manager.
Definition: agentmanager.cpp:377
Akonadi::AgentType
A representation of an agent type.
Definition: agenttype.h:59
Akonadi::Collection
Represents a collection of PIM items.
Definition: collection.h:76
Akonadi
FreeBusyManager::Singleton.
Definition: actionstatemanager_p.h:28
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Jul 21 2022 00:00:00 by doxygen 1.9.5 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

Skip menu "akonadi"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Modules
  • Related Pages

kdepimlibs-4.14.10 API Reference

Skip menu "kdepimlibs-4.14.10 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal