File indexing completed on 2024-05-12 04:45:56
0001 #include "notessyncer.h" 0002 #include "controllers/notes/notescontroller.h" 0003 #include "db/db.h" 0004 0005 #include <QDateTime> 0006 0007 #include <MauiKit3/FileBrowsing/fmstatic.h> 0008 #include <MauiKit3/Accounts/mauiaccounts.h> 0009 #include <MauiKit3/FileBrowsing/tagging.h> 0010 0011 NotesSyncer::NotesSyncer(QObject *parent) 0012 : Syncer(parent) 0013 , tag(Tagging::getInstance()) 0014 , db(DB::getInstance()) 0015 , m_notesController(new NotesController(this)) // local handler for notes 0016 { 0017 connect(MauiAccounts::instance(), &MauiAccounts::currentAccountChanged, [&](QVariantMap) { 0018 this->getRemoteNotes(); 0019 }); 0020 0021 connect(this->m_notesController, &NotesController::noteReady, this, &NotesSyncer::noteReady); 0022 } 0023 0024 void NotesSyncer::insertNote(FMH::MODEL ¬e) 0025 { 0026 if (!this->m_notesController->insertNote(note)) 0027 return; 0028 0029 if (this->validProvider()) 0030 this->getProvider().insertNote(note); 0031 0032 Q_EMIT this->noteInserted(note, {STATE::TYPE::LOCAL, STATE::STATUS::OK, "Note saved locally"}); 0033 } 0034 0035 void NotesSyncer::updateNote(QString id, FMH::MODEL ¬e) 0036 { 0037 if (!this->m_notesController->updateNote(note, id)) 0038 { 0039 qWarning() << "The note could not be updated locally, " 0040 "therefore it was not attempted to update it on the remote server provider, " 0041 "even if it existed."; 0042 return; 0043 } 0044 0045 // to update remote note we need to pass the stamp as the id 0046 const auto stamp = NotesSyncer::noteStampFromId(id); 0047 if (!stamp.isEmpty()) { 0048 if (this->validProvider()) 0049 this->getProvider().updateNote(stamp, note); 0050 } 0051 0052 Q_EMIT this->noteUpdated(note, {STATE::TYPE::LOCAL, STATE::STATUS::OK, "Note updated on the DB locally"}); 0053 } 0054 0055 void NotesSyncer::removeNote(const QString &id) 0056 { 0057 // to remove the remote note we need to pass the stamp as the id, 0058 // and before removing the note locally we need to retireved first 0059 0060 const auto stamp = NotesSyncer::noteStampFromId(id); 0061 if (!this->m_notesController->removeNote(id)) { 0062 qWarning() << "The note could not be inserted locally, " 0063 "therefore it was not attempted to insert it to the remote provider server, " 0064 "even if it existed."; 0065 return; 0066 } 0067 0068 if (!stamp.isEmpty()) { 0069 if (this->validProvider()) 0070 this->getProvider().removeNote(stamp); 0071 } 0072 0073 Q_EMIT this->noteRemoved(FMH::MODEL(), {STATE::TYPE::LOCAL, STATE::STATUS::OK, "The note has been removed from the local DB"}); 0074 } 0075 0076 void NotesSyncer::getNotes() 0077 { 0078 this->getLocalNotes(); 0079 this->getRemoteNotes(); 0080 } 0081 0082 void NotesSyncer::getLocalNotes() 0083 { 0084 this->m_notesController->getNotes(); 0085 } 0086 0087 void NotesSyncer::getRemoteNotes() 0088 { 0089 if (this->validProvider()) 0090 this->getProvider().getNotes(); 0091 else 0092 qWarning() << "Failed to fetch online notes. Credentials are missing or the provider has not been set"; 0093 } 0094 0095 const QString NotesSyncer::noteIdFromStamp(const QString &provider, const QString &stamp) 0096 { 0097 return [&]() -> const QString { 0098 const auto data = DB::getInstance()->getDBData(QString("select id from notes_sync where server = '%1' AND stamp = '%2'").arg(provider, stamp)); 0099 return data.isEmpty() ? QString() : data.first()[FMH::MODEL_KEY::ID]; 0100 }(); 0101 } 0102 0103 const QString NotesSyncer::noteStampFromId(const QString &id) 0104 { 0105 return [&]() -> const QString { 0106 const auto data = DB::getInstance()->getDBData(QString("select stamp from notes_sync where id = '%1'").arg(id)); 0107 return data.isEmpty() ? QString() : data.first()[FMH::MODEL_KEY::STAMP]; 0108 }(); 0109 } 0110 0111 void NotesSyncer::setConections() 0112 { 0113 connect(&this->getProvider(), &AbstractNotesProvider::noteInserted, [&](FMH::MODEL note) { 0114 qDebug() << "STAMP ID OF THE NEWLY INSERTED NOTE" << note[FMH::MODEL_KEY::STAMP] << note; 0115 this->db->insert(OWL::TABLEMAP[OWL::TABLE::NOTES_SYNC], FMH::toMap(FMH::filterModel(note, {FMH::MODEL_KEY::ID, FMH::MODEL_KEY::STAMP, FMH::MODEL_KEY::USER, FMH::MODEL_KEY::SERVER}))); 0116 Q_EMIT this->noteInserted(note, {STATE::TYPE::REMOTE, STATE::STATUS::OK, "Note inserted on the server provider"}); 0117 }); 0118 0119 connect(&this->getProvider(), &AbstractNotesProvider::notesReady, [&](FMH::MODEL_LIST notes) { 0120 // qDebug()<< "SERVER NOETS READY "<< notes; 0121 0122 // if there are no notes in the provider server, then just return 0123 if (notes.isEmpty()) 0124 return; 0125 0126 // there might be two case scenarios: 0127 // the note exists locally in the db, so it needs to be updated with the server version 0128 // the note does not exists locally, so it needs to be inserted into the db 0129 for (auto ¬e : notes) { 0130 const auto id = NotesSyncer::noteIdFromStamp(this->getProvider().provider(), note[FMH::MODEL_KEY::STAMP]); 0131 note[FMH::MODEL_KEY::ID] = id; 0132 note[FMH::MODEL_KEY::FAVORITE] = note[FMH::MODEL_KEY::FAVORITE] == "true" ? "1" : "0"; 0133 qDebug() << "REMOTE NOTE MAPPED ID" << id << note[FMH::MODEL_KEY::STAMP]; 0134 0135 // if the id is empty then the note does not exists, so the note is inserted locally 0136 if (id.isEmpty()) { 0137 if (!this->m_notesController->insertNote(note)) 0138 continue; 0139 0140 this->db->insert(OWL::TABLEMAP[OWL::TABLE::NOTES_SYNC], FMH::toMap(FMH::filterModel(note, {FMH::MODEL_KEY::ID, FMH::MODEL_KEY::STAMP, FMH::MODEL_KEY::USER, FMH::MODEL_KEY::SERVER}))); 0141 Q_EMIT this->noteInserted(note, {STATE::TYPE::LOCAL, STATE::STATUS::OK, "Note inserted on local db, from the server provider"}); 0142 0143 } else { 0144 // the note does exists locally, so update it 0145 note[FMH::MODEL_KEY::URL] = [&]() -> const QString { 0146 const auto data = DB::getInstance()->getDBData(QString("select url from notes where id = '%1'").arg(id)); 0147 return data.isEmpty() ? QString() : data.first()[FMH::MODEL_KEY::URL]; 0148 }(); 0149 0150 auto remoteDate = QDateTime::fromSecsSinceEpoch(note[FMH::MODEL_KEY::MODIFIED].toInt()); 0151 auto localDate = QFileInfo(QUrl(note[FMH::MODEL_KEY::URL]).toLocalFile()).lastModified(); 0152 0153 qDebug() << "UPDATING FROM REMOTE" << note[FMH::MODEL_KEY::URL] << localDate.secsTo(QDateTime::currentDateTime()) << remoteDate.secsTo(QDateTime::currentDateTime()); 0154 0155 if (remoteDate <= localDate) 0156 continue; 0157 0158 if (!this->m_notesController->updateNote(note, id)) 0159 continue; 0160 0161 Q_EMIT this->noteUpdated(note, {STATE::TYPE::LOCAL, STATE::STATUS::OK, "Note updated on local db, from the server provider"}); 0162 } 0163 } 0164 }); 0165 0166 connect(&this->getProvider(), &AbstractNotesProvider::noteUpdated, [&](FMH::MODEL note) { 0167 const auto id = NotesSyncer::noteIdFromStamp(this->getProvider().provider(), note[FMH::MODEL_KEY::STAMP]); 0168 note[FMH::MODEL_KEY::ID] = id; 0169 0170 if (!note.isEmpty()) 0171 this->m_notesController->updateNote(note, id); 0172 Q_EMIT this->noteUpdated(note, {STATE::TYPE::REMOTE, STATE::STATUS::OK, "Note updated on server provider"}); 0173 }); 0174 0175 connect(&this->getProvider(), &AbstractNotesProvider::noteRemoved, [&]() { 0176 Q_EMIT this->noteRemoved(FMH::MODEL(), {STATE::TYPE::REMOTE, STATE::STATUS::OK, "The note has been removed from the remove server provider"}); 0177 }); 0178 }