File indexing completed on 2024-05-12 04:45:55
0001 #include "nextnote.h" 0002 #include <QUrl> 0003 //#include <QDomDocument> 0004 #include <QJsonDocument> 0005 #include <QJsonObject> 0006 #include <QVariantMap> 0007 #include <QNetworkReply> 0008 0009 const QString NextNote::API = QStringLiteral("/index.php/apps/notes/api/v0.2/"); 0010 0011 static const inline QNetworkRequest formRequest(const QUrl &url, const QString &user, const QString &password) 0012 { 0013 if (!url.isValid() && !user.isEmpty() && !password.isEmpty()) 0014 return QNetworkRequest(); 0015 0016 const QString concatenated = user + ":" + password; 0017 const QByteArray data = concatenated.toLocal8Bit().toBase64(); 0018 const QString headerData = "Basic " + data; 0019 0020 // QVariantMap headers 0021 // { 0022 // {"Authorization", headerData.toLocal8Bit()}, 0023 // {QString::number(QNetworkRequest::ContentTypeHeader),"application/json"} 0024 // }; 0025 0026 QNetworkRequest request; 0027 request.setUrl(QUrl(url)); 0028 request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); 0029 request.setRawHeader(QString("Authorization").toLocal8Bit(), headerData.toLocal8Bit()); 0030 0031 return request; 0032 } 0033 0034 NextNote::NextNote(QObject *parent) 0035 : AbstractNotesProvider(parent) 0036 { 0037 } 0038 0039 NextNote::~NextNote() 0040 { 0041 } 0042 0043 void NextNote::getNote(const QString &id) 0044 { 0045 QUrl relativeUrl("../.." + NextNote::API + QString("notes/%1").arg(id)); 0046 auto url = QUrl(this->m_provider).resolved(relativeUrl); 0047 qDebug() << "THE RESOLVED URL IS" << url << this->m_provider; 0048 0049 // const auto request = formRequest(url, this->m_user, this->m_password); 0050 QString concatenated = this->m_user + ":" + this->m_password; 0051 QByteArray data = concatenated.toLocal8Bit().toBase64(); 0052 QString headerData = "Basic " + data; 0053 0054 QMap<QString, QString> header{{"Authorization", headerData.toLocal8Bit()}}; 0055 0056 auto downloader = new FMH::Downloader; 0057 connect(downloader, &FMH::Downloader::dataReady, [=](QByteArray array) { 0058 const auto notes = this->parseNotes(array); 0059 Q_EMIT this->noteReady(notes.isEmpty() ? FMH::MODEL() : notes.first()); 0060 downloader->deleteLater(); 0061 }); 0062 0063 downloader->getArray(url, header); 0064 } 0065 0066 void NextNote::getBooklet(const QString &id) 0067 { 0068 Q_UNUSED(id) 0069 } 0070 0071 void NextNote::sendNotes(QByteArray array) 0072 { 0073 Q_UNUSED(array) 0074 // Q_EMIT this->notesReady(notes); 0075 } 0076 0077 void NextNote::getNotes() 0078 { 0079 QUrl relativeUrl("../.." + NextNote::API + QString("notes")); 0080 auto url = QUrl(this->m_provider).resolved(relativeUrl); 0081 qDebug() << "THE RESOLVED URL IS" << url << this->m_provider; 0082 0083 QString concatenated = this->m_user + ":" + this->m_password; 0084 QByteArray data = concatenated.toLocal8Bit().toBase64(); 0085 QString headerData = "Basic " + data; 0086 0087 QMap<QString, QString> header{{"Authorization", headerData.toLocal8Bit()}}; 0088 0089 const auto downloader = new FMH::Downloader; 0090 connect(downloader, &FMH::Downloader::dataReady, [=](QByteArray array) { 0091 // exclude notes that have its own category 0092 FMH::MODEL_LIST notes; 0093 for (const auto &data : this->parseNotes(array)) { 0094 auto item = data; 0095 item[FMH::MODEL_KEY::STAMP] = item[FMH::MODEL_KEY::ID]; 0096 item[FMH::MODEL_KEY::USER] = this->user(); 0097 item[FMH::MODEL_KEY::SERVER] = this->provider(); 0098 item[FMH::MODEL_KEY::FORMAT] = ".txt"; 0099 0100 if (item[FMH::MODEL_KEY::CATEGORY].isEmpty() || item[FMH::MODEL_KEY::CATEGORY].isNull()) 0101 notes << item; 0102 } 0103 0104 Q_EMIT this->notesReady(notes); 0105 downloader->deleteLater(); 0106 }); 0107 0108 downloader->getArray(url, header); 0109 } 0110 0111 void NextNote::getBooklets() 0112 { 0113 QUrl relativeUrl("../.." + NextNote::API + QString("notes")); 0114 auto url = QUrl(this->m_provider).resolved(relativeUrl); 0115 qDebug() << "THE RESOLVED URL IS" << url << this->m_provider; 0116 0117 QString concatenated = this->m_user + ":" + this->m_password; 0118 QByteArray data = concatenated.toLocal8Bit().toBase64(); 0119 QString headerData = "Basic " + data; 0120 0121 QMap<QString, QString> header{{"Authorization", headerData.toLocal8Bit()}}; 0122 0123 const auto downloader = new FMH::Downloader; 0124 connect(downloader, &FMH::Downloader::dataReady, [=](QByteArray array) { 0125 // exclude notes that do not have their own category 0126 FMH::MODEL_LIST booklets; 0127 for (const auto &data : this->parseNotes(array)) { 0128 auto item = data; 0129 item[FMH::MODEL_KEY::STAMP] = item[FMH::MODEL_KEY::ID]; 0130 item[FMH::MODEL_KEY::USER] = this->user(); 0131 item[FMH::MODEL_KEY::SERVER] = this->provider(); 0132 item[FMH::MODEL_KEY::FORMAT] = ".txt"; 0133 0134 if (!item[FMH::MODEL_KEY::CATEGORY].isEmpty() && !item[FMH::MODEL_KEY::CATEGORY].isNull()) 0135 booklets << item; 0136 } 0137 0138 Q_EMIT this->bookletsReady(booklets); 0139 downloader->deleteLater(); 0140 }); 0141 0142 downloader->getArray(url, header); 0143 } 0144 0145 void NextNote::insertNote(const FMH::MODEL ¬e) 0146 { 0147 QByteArray payload = QJsonDocument::fromVariant(FMH::toMap(FMH::filterModel(note, {FMH::MODEL_KEY::CONTENT, FMH::MODEL_KEY::FAVORITE}))).toJson(); 0148 qDebug() << "UPLOADING NEW NOT" << QVariant(payload).toString(); 0149 0150 QUrl relativeUrl("../.." + NextNote::API + QString("notes")); 0151 auto url = QUrl(this->m_provider).resolved(relativeUrl); 0152 qDebug() << "THE RESOLVED URL IS" << url << this->m_provider; 0153 0154 const auto request = formRequest(url, this->m_user, this->m_password); 0155 0156 auto restclient = new QNetworkAccessManager; // constructor 0157 QNetworkReply *reply = restclient->post(request, payload); 0158 connect(reply, &QNetworkReply::finished, [=, __note = note]() { 0159 qDebug() << "Note insertyion finished?"; 0160 const auto notes = this->parseNotes(reply->readAll()); 0161 Q_EMIT this->noteInserted([&]() -> FMH::MODEL { 0162 FMH::MODEL note; 0163 if (!notes.isEmpty()) { 0164 note = notes.first(); 0165 note[FMH::MODEL_KEY::STAMP] = note[FMH::MODEL_KEY::ID]; // adds the id of the uploaded note as a stamp 0166 note[FMH::MODEL_KEY::ID] = __note[FMH::MODEL_KEY::ID]; // adds the url of the original local note 0167 note[FMH::MODEL_KEY::SERVER] = this->m_provider; // adds the provider server address 0168 note[FMH::MODEL_KEY::USER] = this->m_user; // adds the user name 0169 } 0170 return note; 0171 }()); 0172 0173 reply->deleteLater(); 0174 restclient->deleteLater(); 0175 }); 0176 } 0177 0178 void NextNote::insertBooklet(const FMH::MODEL &booklet) 0179 { 0180 QByteArray payload = QJsonDocument::fromVariant(FMH::toMap(FMH::filterModel(booklet, {FMH::MODEL_KEY::CONTENT, FMH::MODEL_KEY::FAVORITE, FMH::MODEL_KEY::CATEGORY}))).toJson(); 0181 qDebug() << "UPLOADING NEW BOOKLET" << QVariant(payload).toString(); 0182 0183 QUrl relativeUrl("../.." + NextNote::API + QString("notes")); 0184 auto url = QUrl(this->m_provider).resolved(relativeUrl); 0185 qDebug() << "THE RESOLVED URL IS" << url << this->m_provider; 0186 0187 const auto request = formRequest(url, this->m_user, this->m_password); 0188 0189 auto restclient = new QNetworkAccessManager; // constructor 0190 QNetworkReply *reply = restclient->post(request, payload); 0191 connect(reply, &QNetworkReply::finished, [=, __booklet = booklet]() { 0192 qDebug() << "Note insertyion finished?"; 0193 const auto booklets = this->parseNotes(reply->readAll()); 0194 Q_EMIT this->bookletInserted([&]() -> FMH::MODEL { 0195 FMH::MODEL p_booklet; 0196 if (!booklets.isEmpty()) { 0197 p_booklet = booklets.first(); 0198 p_booklet[FMH::MODEL_KEY::STAMP] = p_booklet[FMH::MODEL_KEY::ID]; // adds the id of the local note as a stamp 0199 p_booklet[FMH::MODEL_KEY::ID] = __booklet[FMH::MODEL_KEY::ID]; // adds the id of the local note as a stamp 0200 p_booklet[FMH::MODEL_KEY::SERVER] = this->m_provider; // adds the provider server address 0201 p_booklet[FMH::MODEL_KEY::USER] = this->m_user; // adds the user name 0202 } 0203 return p_booklet; 0204 }()); 0205 0206 restclient->deleteLater(); 0207 reply->deleteLater(); 0208 }); 0209 } 0210 0211 void NextNote::updateNote(const QString &id, const FMH::MODEL ¬e) 0212 { 0213 if (id.isEmpty() || note.isEmpty()) { 0214 qWarning() << "The id or note are empty. Can not proceed. NextNote::update"; 0215 return; 0216 } 0217 0218 QByteArray payload = QJsonDocument::fromVariant(FMH::toMap(FMH::filterModel(note, {FMH::MODEL_KEY::CONTENT, FMH::MODEL_KEY::FAVORITE, FMH::MODEL_KEY::MODIFIED, FMH::MODEL_KEY::CATEGORY}))).toJson(); 0219 qDebug() << "UPDATING NOTE" << QVariant(payload).toString(); 0220 0221 QUrl relativeUrl("../.." + NextNote::API + QString("notes/%1").arg(id)); 0222 auto url = QUrl(this->m_provider).resolved(relativeUrl); 0223 qDebug() << "THE RESOLVED URL IS" << url << this->m_provider; 0224 0225 qDebug() << "tryiong to update note" << url; 0226 const auto request = formRequest(url, this->m_user, this->m_password); 0227 0228 auto restclient = new QNetworkAccessManager; // constructor 0229 QNetworkReply *reply = restclient->put(request, payload); 0230 connect(reply, &QNetworkReply::finished, [=, __note = note]() { 0231 qDebug() << "Note update finished?" << reply->errorString(); 0232 const auto notes = this->parseNotes(reply->readAll()); 0233 Q_EMIT this->noteUpdated([&]() -> FMH::MODEL { 0234 FMH::MODEL note; 0235 if (notes.isEmpty()) 0236 return note; 0237 0238 note = notes.first(); 0239 note[FMH::MODEL_KEY::STAMP] = note[FMH::MODEL_KEY::ID]; // adds the id of the local note as a stamp 0240 note[FMH::MODEL_KEY::ID] = __note[FMH::MODEL_KEY::ID]; // adds the id of the local note as a stamp 0241 note[FMH::MODEL_KEY::SERVER] = this->m_provider; // adds the provider server address 0242 note[FMH::MODEL_KEY::USER] = this->m_user; // adds the user name 0243 0244 return note; 0245 }()); 0246 0247 restclient->deleteLater(); 0248 reply->deleteLater(); 0249 }); 0250 } 0251 0252 void NextNote::updateBooklet(const QString &id, const FMH::MODEL &booklet) 0253 { 0254 if (id.isEmpty() || booklet.isEmpty()) { 0255 qWarning() << "The id or note are empty. Can not proceed. NextNote::update"; 0256 return; 0257 } 0258 0259 QByteArray payload = QJsonDocument::fromVariant(FMH::toMap(FMH::filterModel(booklet, {FMH::MODEL_KEY::CONTENT, FMH::MODEL_KEY::CATEGORY}))).toJson(); 0260 qDebug() << "UPDATING BOOKLET" << QVariant(payload).toString(); 0261 0262 QUrl relativeUrl("../.." + NextNote::API + QString("notes/%1").arg(id)); 0263 auto url = QUrl(this->m_provider).resolved(relativeUrl); 0264 qDebug() << "THE RESOLVED URL IS" << url << this->m_provider; 0265 0266 qDebug() << "tryiong to update note" << url; 0267 const auto request = formRequest(url, this->m_user, this->m_password); 0268 0269 auto restclient = new QNetworkAccessManager; // constructor 0270 QNetworkReply *reply = restclient->put(request, payload); 0271 connect(reply, &QNetworkReply::finished, [=, __booklet = booklet]() { 0272 qDebug() << "Note update finished?" << reply->errorString(); 0273 const auto booklets = this->parseNotes(reply->readAll()); 0274 Q_EMIT this->bookletUpdated([&]() -> FMH::MODEL { 0275 FMH::MODEL booklet; 0276 0277 if (booklets.isEmpty()) 0278 return booklet; 0279 0280 booklet = booklets.first(); 0281 booklet[FMH::MODEL_KEY::STAMP] = booklet[FMH::MODEL_KEY::ID]; // adds the stamp to the local note form the remote id 0282 booklet[FMH::MODEL_KEY::ID] = __booklet[FMH::MODEL_KEY::ID]; // adds back the id of the local booklet 0283 booklet[FMH::MODEL_KEY::SERVER] = this->m_provider; // adds the provider server address 0284 booklet[FMH::MODEL_KEY::USER] = this->m_user; // adds the user name 0285 0286 return booklet; 0287 }()); 0288 0289 restclient->deleteLater(); 0290 reply->deleteLater(); 0291 }); 0292 } 0293 0294 void NextNote::removeNote(const QString &id) 0295 { 0296 if (id.isEmpty()) { 0297 qWarning() << "The id is empty. Can not proceed. NextNote::remove"; 0298 return; 0299 } 0300 0301 QUrl relativeUrl("../.." + NextNote::API + QString("notes/%1").arg(id)); 0302 auto url = QUrl(this->m_provider).resolved(relativeUrl); 0303 qDebug() << "THE RESOLVED URL IS" << url << this->m_provider; 0304 0305 const auto request = formRequest(url, this->m_user, this->m_password); 0306 qDebug() << "trying to remove nextnote <<" << url; 0307 auto restclient = new QNetworkAccessManager; // constructor 0308 QNetworkReply *reply = restclient->deleteResource(request); 0309 connect(reply, &QNetworkReply::finished, [=]() { 0310 qDebug() << "Note remove finished?" << reply->errorString(); 0311 Q_EMIT this->noteRemoved(); 0312 restclient->deleteLater(); 0313 reply->deleteLater(); 0314 }); 0315 } 0316 0317 void NextNote::removeBooklet(const QString &id) 0318 { 0319 this->removeNote(id); 0320 } 0321 0322 const FMH::MODEL_LIST NextNote::parseNotes(const QByteArray &array) 0323 { 0324 FMH::MODEL_LIST res; 0325 // qDebug()<< "trying to parse notes" << array; 0326 QJsonParseError jsonParseError; 0327 QJsonDocument jsonResponse = QJsonDocument::fromJson(static_cast<QString>(array).toUtf8(), &jsonParseError); 0328 0329 if (jsonParseError.error != QJsonParseError::NoError) { 0330 qDebug() << "ERROR PARSING" << array; 0331 return res; 0332 } 0333 0334 const auto data = jsonResponse.toVariant(); 0335 0336 if (data.isNull() || !data.isValid()) 0337 return res; 0338 0339 if (!data.toList().isEmpty()) 0340 res << FMH::toModelList(data.toList()); 0341 else 0342 res << FMH::toModel(data.toMap()); 0343 0344 return res; 0345 }