File indexing completed on 2024-06-09 05:16:15

0001 /*
0002  * Copyright (c) 2019 Alexander Potashev <aspotashev@gmail.com>
0003  *
0004  * This program is free software; you can redistribute it and/or
0005  * modify it under the terms of the GNU General Public License as
0006  * published by the Free Software Foundation; either version 2 of
0007  * the License or (at your option) version 3 or any later version
0008  * accepted by the membership of KDE e.V. (or its successor approved
0009  * by the membership of KDE e.V.), which shall act as a proxy
0010  * defined in Section 14 of version 3 of the license.
0011  *
0012  * This program is distributed in the hope that it will be useful,
0013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0015  * GNU General Public License for more details.
0016  *
0017  * You should have received a copy of the GNU General Public License
0018  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0019  */
0020 
0021 #include "icalformatkio.h"
0022 
0023 #include <QSaveFile>
0024 
0025 #include <KCalendarCore/Exceptions>
0026 
0027 #include <KIO/StoredTransferJob>
0028 #include <KJobWidgets>
0029 #include "ktt_debug.h"
0030 
0031 bool ICalFormatKIO::load(const KCalendarCore::Calendar::Ptr &calendar, const QString &urlString)
0032 {
0033     qCDebug(KTT_LOG) << "ICalFormatKIO::load:" << urlString;
0034 
0035     clearException();
0036 
0037     QUrl url(urlString);
0038     if (url.isLocalFile()) {
0039         QFile file(url.toLocalFile());
0040         if (!file.exists()) {
0041             // Local file does not exist
0042             return true;
0043         }
0044 
0045         // Local file exists
0046         if (!file.open(QIODevice::ReadOnly)) {
0047             qCWarning(KTT_LOG) << "load file open error: " << file.errorString() << ";filename=" << urlString;
0048             setException(new KCalendarCore::Exception(KCalendarCore::Exception::LoadError));
0049             return false;
0050         }
0051         const QByteArray text = file.readAll().trimmed();
0052         file.close();
0053 
0054         if (text.isEmpty()) {
0055             // empty files are valid
0056             return true;
0057         } else {
0058             return fromRawString(calendar, text);
0059         }
0060     } else {
0061         // use remote file
0062         auto *const job = KIO::storedGet(url, KIO::Reload);
0063         KJobWidgets::setWindow(job, nullptr); // hide progress notification
0064         if (!job->exec()) {
0065             setException(new KCalendarCore::Exception(KCalendarCore::Exception::SaveErrorSaveFile, QStringList(url.url())));
0066             return false;
0067         }
0068 
0069         const QByteArray text = job->data();
0070         if (text.isEmpty()) {
0071             // empty files are valid
0072             return true;
0073         } else {
0074             return fromRawString(calendar, text);
0075         }
0076     }
0077 }
0078 
0079 bool ICalFormatKIO::save(const KCalendarCore::Calendar::Ptr &calendar, const QString &urlString)
0080 {
0081     qCDebug(KTT_LOG) << "ICalFormatKIO::save:" << urlString;
0082 
0083     clearException();
0084 
0085     QString text = toString(calendar);
0086     if (text.isEmpty()) {
0087         // TODO: save empty file if we have 0 tasks?
0088         return false;
0089     }
0090 
0091     QByteArray textUtf8 = text.toUtf8();
0092 
0093     // TODO: Write backup file (i.e. backup the existing file somewhere, e.g. to ~/.local/share/apps/ktimetracker/backups/)
0094 //    const QString backupFile = urlString + QLatin1Char('~');
0095 //    QFile::remove(backupFile);
0096 //    QFile::copy(urlString, backupFile);
0097 
0098     // save, either locally or remote
0099     QUrl url(urlString);
0100     if (url.isLocalFile()) {
0101         QSaveFile file(url.toLocalFile());
0102         if (!file.open(QIODevice::WriteOnly)) {
0103             qCWarning(KTT_LOG) << "save file open error: " << file.errorString() << ";local path" << file.fileName();
0104             setException(new KCalendarCore::Exception(KCalendarCore::Exception::SaveErrorOpenFile, QStringList(urlString)));
0105             return false;
0106         }
0107 
0108         file.write(textUtf8.data(), textUtf8.size());
0109 
0110         if (!file.commit()) {
0111             qCWarning(KTT_LOG) << "file finalize error:" << file.errorString() << ";local path" << file.fileName();
0112             setException(new KCalendarCore::Exception(KCalendarCore::Exception::SaveErrorSaveFile, QStringList(urlString)));
0113             return false;
0114         }
0115     } else {
0116         // use remote file
0117         auto *const job = KIO::storedPut(textUtf8, url, -1, KIO::Overwrite);
0118         KJobWidgets::setWindow(job, nullptr); // hide progress notification
0119         if (!job->exec()) {
0120             setException(new KCalendarCore::Exception(KCalendarCore::Exception::SaveErrorSaveFile, QStringList(url.url())));
0121             qCWarning(KTT_LOG) << "save remote error: " << job->errorString();
0122             return false;
0123         }
0124     }
0125 
0126     return true;
0127 }