// Update the user's notebook name list void NoteTable::updateNoteListNotebooks(QString guid, QString name) { NotebookTable notebookTable; qint32 notebookLid; notebookLid = notebookTable.getLid(guid); QSqlQuery sql2; sql2.prepare("Update NoteTable set notebook=:note where lid=:lid"); sql2.bindValue(":note", name); sql2.bindValue(":lid", notebookLid); sql2.exec(); }
qint32 NoteTable::findNotesByNotebook(QList<qint32> ¬es, QString guid) { QSqlQuery query; qint32 notebookLid; NotebookTable notebookTable; notebookLid = notebookTable.getLid(guid); query.prepare("Select lid from DataStore where key=:key and data=:notebookLid"); query.bindValue(":key", NOTE_NOTEBOOK_LID); query.bindValue(":notebookLid", notebookLid); query.exec(); while (query.next()) { notes.append(query.value(0).toInt()); } return notes.size(); }
bool NoteTable::updateNoteList(qint32 lid, Note &t, bool isDirty) { NotebookTable notebookTable; qint32 notebookLid = notebookTable.getLid(t.notebookGuid); Notebook notebook; notebookTable.get(notebook, notebookLid); // Now let's update the user table QSqlQuery query; query.prepare("Delete from NoteTable where lid=:lid"); query.bindValue(":lid", lid); query.exec(); query.prepare(QString("Insert into NoteTable (lid, title, author, ") + QString("dateCreated, dateUpdated, dateSubject, dateDeleted, source, sourceUrl, sourceApplication, ") + QString("latitude, longitude, altitude, hasEncryption, hasTodo, isDirty, size, notebook, notebookLid, tags) ") + QString("Values (:lid, :title, :author, ") + QString(":dateCreated, :dateUpdated, :dateSubject, :dateDeleted, :source, :sourceUrl, :sourceApplication, ") + QString(":latitude, :longitude, :altitude, :hasEncryption, :hasTodo, :isDirty, :size, :notebook, :notebookLid, :tags) ")) ; query.bindValue(":lid", lid); if (t.__isset.title) query.bindValue(":title", QString::fromStdString(t.title)); else query.bindValue(":title", ""); if (t.__isset.attributes && t.attributes.__isset.author) query.bindValue(":author", QString::fromStdString(t.attributes.author)); else query.bindValue(":author", ""); if (t.__isset.created) query.bindValue(":dateCreated", QVariant::fromValue(t.created)); else query.bindValue(":dateCreated", 0); if (t.__isset.updated) query.bindValue(":dateUpdated", QVariant::fromValue(t.updated)); else query.bindValue(":dateUpdated", 0); if (t.__isset.attributes && t.attributes.__isset.subjectDate) query.bindValue(":dateSubject", QVariant::fromValue(t.attributes.subjectDate)); else query.bindValue(":dateSubject", 0); if (t.__isset.deleted) query.bindValue(":dateDeleted", QVariant::fromValue(t.deleted)); else query.bindValue(":dateDeleted", 0); if (t.__isset.attributes && t.attributes.__isset.source) query.bindValue(":source", QString::fromStdString(t.attributes.source)); else query.bindValue(":source", ""); if (t.__isset.attributes && t.attributes.__isset.sourceURL) query.bindValue(":sourceUrl", QString::fromStdString(t.attributes.sourceURL)); else query.bindValue(":sourceUrl", ""); if (t.__isset.attributes && t.attributes.__isset.sourceApplication) query.bindValue(":sourceApplication", QString::fromStdString(t.attributes.sourceApplication)); else query.bindValue(":sourceApplication", ""); if (t.__isset.attributes && t.attributes.__isset.latitude) query.bindValue(":latitude", QVariant::fromValue(t.attributes.latitude)); else query.bindValue(":latitude", 0); if (t.__isset.attributes && t.attributes.__isset.longitude) query.bindValue(":longitude", QVariant::fromValue(t.attributes.longitude)); else query.bindValue(":longitude", 0); if (t.__isset.attributes && t.attributes.__isset.altitude) query.bindValue(":altitude", QVariant::fromValue(t.attributes.altitude)); else query.bindValue(":altitude", 0); bool hasEncryption; if (t.content.find("<en-crypt") != string::npos) hasEncryption = true; else hasEncryption = false; query.bindValue(":hasEncryption", hasEncryption); bool hasTodo; if (t.content.find("<en-todo") != string::npos) hasTodo = true; else hasTodo = false; query.bindValue(":hasTodo", hasTodo); query.bindValue(":isDirty", isDirty); qlonglong size = t.content.length(); for (unsigned int i=0; i<t.resources.size(); i++) { size+=t.resources[i].data.size; } query.bindValue(":size", size); query.bindValue(":notebook", QString::fromStdString(notebook.name)); query.bindValue(":notebookLid", notebookLid); QString tagNames; QStringList sortedNames; for (unsigned int i=0; i<t.tagNames.size(); i++) { sortedNames.append(QString::fromStdString(t.tagNames.at(i)).toLower()); } sortedNames.sort(); TagTable tagTable; LinkedNotebookTable linkedTable; qint32 account = 0; notebookLid = notebookTable.getLid(t.notebookGuid); if (linkedTable.exists(notebookLid)) account = notebookLid; for (int i=0; i<sortedNames.size(); i++) { if (i>0) tagNames = tagNames+", "; Tag currentTag; qint32 tagLid = tagTable.findByName(sortedNames[i], account); tagTable.get(currentTag, tagLid); tagNames = tagNames + QString::fromStdString(currentTag.name); } query.bindValue(":tags", tagNames); if (!query.exec()) { QLOG_ERROR() << "Error inserting into NoteTable: " << query.lastError(); return false; } return true; }
// Add a new note to the database qint32 NoteTable::add(qint32 l, Note &t, bool isDirty) { QLOG_DEBUG() << "Adding note: " << QString::fromStdString(t.title); ResourceTable resTable; ConfigStore cs; QSqlQuery query; qint32 position; TagScanner scanner; qint32 lid = l; qint32 notebookLid; query.prepare("Insert into DataStore (lid, key, data) values (:lid, :key, :data)"); if (lid <= 0) lid = cs.incrementLidCounter(); query.bindValue(":lid", lid); query.bindValue(":key", NOTE_GUID); query.bindValue(":data", QString::fromStdString(t.guid)); query.exec(); query.bindValue(":lid", lid); query.bindValue(":key", NOTE_INDEX_NEEDED); query.bindValue(":data", true); query.exec(); if (t.__isset.title) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_TITLE); query.bindValue(":data", QString::fromStdString(t.title.c_str())); query.exec(); } if (t.__isset.content) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_CONTENT); QByteArray b; b.append(QString::fromStdString(t.content).toAscii()); query.bindValue(":data", b); query.exec(); } if (t.__isset.contentHash) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_CONTENT_HASH); query.bindValue(":data", QString::fromStdString(t.contentHash)); query.exec(); } if (t.__isset.contentLength) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_CONTENT_LENGTH); query.bindValue(":data", t.contentLength); query.exec(); } query.bindValue(":lid", lid); query.bindValue(":key", NOTE_UPDATE_SEQUENCE_NUMBER); query.bindValue(":data", t.updateSequenceNum); query.exec(); query.bindValue(":lid", lid); query.bindValue(":key", NOTE_ISDIRTY); query.bindValue(":data", isDirty); query.exec(); if (t.__isset.created) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_CREATED_DATE); query.bindValue(":data", QVariant::fromValue(t.created)); query.exec(); } if (t.__isset.updated) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_UPDATED_DATE); query.bindValue(":data", QVariant::fromValue(t.updated)); query.exec(); } if (t.__isset.deleted) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_DELETED_DATE); query.bindValue(":data", QVariant::fromValue(t.deleted)); query.exec(); } if (t.__isset.active) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_ACTIVE); query.bindValue(":data", QVariant::fromValue(t.active)); query.exec(); } if (t.__isset.notebookGuid) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_NOTEBOOK_LID); NotebookTable notebookTable; notebookLid = notebookTable.getLid(QString::fromStdString(t.notebookGuid)); // If not found, we insert one to avoid problems. We'll probably get the real data later if (notebookLid == 0) { notebookLid = cs.incrementLidCounter(); Notebook notebook; notebook.guid = t.notebookGuid; notebook.name = ""; notebook.__isset.guid = true; notebook.__isset.name = true; notebookTable.add(notebookLid, notebook, false, false); } query.bindValue(":data", notebookLid); query.exec(); } for (unsigned int i=0; t.__isset.tagGuids && i<t.tagGuids.size(); i++) { TagTable tagTable; qint32 tagLid = tagTable.getLid(t.tagGuids.at(i)); if (tagLid == 0) { // create a dummy tag to avoid later problems Tag newTag; newTag.guid = t.tagGuids.at(i); newTag.name = ""; newTag.__isset.guid = true; newTag.__isset.name = true; tagLid = cs.incrementLidCounter(); tagTable.add(tagLid, newTag, false, 0); } query.bindValue(":lid", lid); query.bindValue(":key", NOTE_TAG_LID); query.bindValue(":data", tagLid); query.exec(); } for (unsigned int i=0; t.__isset.resources && i<t.resources.size(); i++) { qint32 resLid; Resource *r; r = &t.resources[i]; resLid = resTable.getLid(t.guid,t.resources[i].guid); if (resLid == 0) resLid = cs.incrementLidCounter(); resTable.add(resLid, t.resources[i], isDirty); if (r->__isset.mime) { QString mime = QString::fromStdString(r->mime); if (!mime.startsWith("image/") && mime != "vnd.evernote.ink") { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_HAS_ATTACHMENT); query.bindValue(":data", true); query.exec(); } } } if (t.__isset.attributes) { if (t.attributes.__isset.subjectDate) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_ATTRIBUTE_SUBJECT_DATE); query.bindValue(":data", QVariant::fromValue(t.attributes.subjectDate)); query.exec(); } if (t.attributes.__isset.latitude) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_ATTRIBUTE_LATITUDE); query.bindValue(":data", QVariant::fromValue(t.attributes.latitude)); query.exec(); } if (t.attributes.__isset.latitude) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_ATTRIBUTE_LONGITUDE); query.bindValue(":data", QVariant::fromValue(t.attributes.longitude)); query.exec(); } if (t.attributes.__isset.altitude) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_ATTRIBUTE_ALTITUDE); query.bindValue(":data", QVariant::fromValue(t.attributes.altitude)); query.exec(); } if (t.attributes.__isset.author) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_ATTRIBUTE_AUTHOR); query.bindValue(":data", QString::fromStdString(t.attributes.author)); query.exec(); } if (t.attributes.__isset.source) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_ATTRIBUTE_SOURCE); query.bindValue(":data", QString::fromStdString(t.attributes.source)); query.exec(); } if (t.attributes.__isset.sourceURL) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_ATTRIBUTE_SOURCE_URL); query.bindValue(":data", QString::fromStdString(t.attributes.sourceURL)); query.exec(); } if (t.attributes.__isset.sourceApplication) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_ATTRIBUTE_SOURCE_APPLICATION); query.bindValue(":data", QString::fromStdString(t.attributes.sourceApplication)); query.exec(); } if (t.attributes.__isset.shareDate) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_ATTRIBUTE_SHARE_DATE); query.bindValue(":data",QVariant::fromValue(t.attributes.shareDate)); query.exec(); } if (t.attributes.__isset.placeName) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_ATTRIBUTE_PLACE_NAME); query.bindValue(":data", QString::fromStdString(t.attributes.placeName)); query.exec(); } if (t.attributes.__isset.contentClass) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_ATTRIBUTE_CONTENT_CLASS); query.bindValue(":data", QString::fromStdString(t.attributes.contentClass)); query.exec(); } } // No determine some attributes of the note based upon the content // This should probably happen every time a note changes? Or at least something simular: QString content; if (t.__isset.content) content = QString::fromStdString(t.content); else content = ""; position = content.indexOf("<en-crypt"); if (position > 0) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_HAS_ENCRYPT); query.bindValue(":data", true); query.exec(); } position = content.indexOf("<en-todo"); if (position > 0) { position = content.indexOf("<en-todo checked=\"true\""); if (position > 0) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_HAS_TODO_COMPLETED); query.bindValue(":data", true); query.exec(); } position = qMax(content.indexOf("<en-todo checked=\"false\""), content.indexOf("<en-todo>")); if (position > 0) { query.bindValue(":lid", lid); query.bindValue(":key", NOTE_HAS_TODO_UNCOMPLETED); query.bindValue(":data", true); query.exec(); } } updateNoteList(lid, t, isDirty); return lid; }
//*********************************************************** //* Process a <notebook> node //*********************************************************** void ImportData::processNotebookNode() { Notebook notebook; bool notebookIsDirty = false; bool notebookIsLocal = false; bool notebookIsReadOnly = false; // notebookIcon = null; bool atEnd = false; // Loop through until we hit </notebook> while(!atEnd) { if (backup || importNotebooks) { if (reader->isStartElement()) { QString name = reader->name().toString().toLower(); if (name == "guid") { notebook.guid = textValue().toStdString(); notebook.__isset.guid = true; } if (name == "name") { notebook.name = textValue().toStdString(); notebook.__isset.name = true; } if (name == "updatesequencenumber") { notebook.updateSequenceNum = intValue(); notebook.__isset.updateSequenceNum = true; } if (name == "servicecreated") { notebook.serviceCreated = longValue(); notebook.__isset.serviceCreated = true; } if (name == "serviceupdated") { notebook.serviceUpdated = longValue(); notebook.__isset.serviceUpdated = true; } if (name == "defaultnotebook") { notebook.defaultNotebook = booleanValue(); notebook.__isset.defaultNotebook = true; } if (name == "dirty") { if (booleanValue()) notebookIsDirty = true; } if (name == "localnotebook") { if (booleanValue()) notebookIsLocal = true; } if (name == "readonly") { if (booleanValue()) notebookIsReadOnly = true; } if (name == "publishingpublicdescription") { notebook.publishing.publicDescription = textValue().toStdString(); notebook.publishing.__isset.publicDescription = true; } if (name == "publishinguri") { notebook.publishing.uri = textValue().toStdString(); notebook.publishing.__isset.uri = true; } if (name == "publishingorder") { //notebook->publishing.order = // NoteSortOrder.; QLOG_DEBUG() << "!!!!!!!!!!!! PublishingOrder not completed in import"; } if (name == "PublishingAscending") { if (booleanValue()) notebook.publishing.ascending = true; else notebook.publishing.ascending = false; notebook.publishing.__isset.ascending = true; } if (name == "icon") { //byte[] b = textValue().getBytes(); // data binary //QByteArray hexData = new QByteArray(b); //QByteArray binData = new QByteArray(QByteArray.fromHex(hexData)); //notebookIcon = new QIcon(QPixmap.fromImage(QImage.fromData(binData))); } if (name == "stack") { notebook.stack = textValue().toStdString(); notebook.__isset.stack = true; } } } reader->readNext(); QString endName = reader->name().toString().toLower(); if (endName == "notebook" && reader->isEndElement()) atEnd = true; } // We are at the end. We should have a valid notebook now NotebookTable notebookTable; // Check if there is a notebook by this name already. // If one exists, we treat this as an update qint32 lid = notebookTable.findByName(notebook.name); if (lid == 0) lid = notebookTable.getLid(notebook.guid); if (lid == 0) { notebookTable.add(lid,notebook,notebookIsDirty, notebookIsLocal); } else { notebookTable.sync(lid, notebook); notebookTable.setDirty(lid, notebookIsDirty); } return; }
/* Take the ENML note and transform it into HTML that WebKit will not complain about */ QByteArray NoteFormatter::rebuildNoteHTML() { QLOG_DEBUG() << "Rebuilding Note: " << QString::fromStdString(note.guid) << " : " << QString::fromStdString(note.title); formatError = false; readOnly = false; // First try to read the document. If it fails we need to clean it up content.append(QString::fromStdString(note.content)); QDomDocument doc; QString emsg; bool goodReturn = doc.setContent(content, &emsg); if (!goodReturn) { QLOG_DEBUG() << "Error with initial document: " << emsg << " running through tidy"; // Run it through "tidy". It is a program which will fix any invalid XML // and give us the results back through stdout. In a perfect world this // wouldn't be needed, but I've seen times where the ENML is bad for some reason. QProcess tidyProcess; tidyProcess.start("tidy -xml -raw -q -e", QIODevice::ReadWrite|QIODevice::Unbuffered); QLOG_DEBUG() << "Starting tidy " << tidyProcess.waitForStarted(); QByteArray b; b.append(QString::fromStdString(note.content)); tidyProcess.write(b); tidyProcess.closeWriteChannel(); QLOG_DEBUG() << "Stopping tidy " << tidyProcess.waitForFinished() << " Return Code: " << tidyProcess.state(); QLOG_DEBUG() << "Tidy Errors:" << tidyProcess.readAllStandardError(); content = tidyProcess.readAllStandardOutput(); // If the content is null, then we had a problem. Just risk going forward without tidy cleanup if (content.size() == 0) content = b; doc.setContent(content); } QLOG_DEBUG() << doc.toString(); // Remove all the temporary file names tempFiles.clear(); modifyTags(doc); // If we have search criteria, then do the highlighting if (enableHighlight) doc = addHighlight(doc); // Finish up and return the HTML to the user QDomElement docElem = doc.documentElement(); docElem.setTagName("body"); content = doc.toByteArray(3); qint32 index = content.indexOf("<body"); content.remove(0,index); content.prepend("<style type=\"text/css\">.en-crypt-temp { border-collapse:collapse; border-style:solid; border-color:blue; padding:0.0mm 0.0mm 0.0mm 0.0mm; }</style>"); content.prepend("<style type=\"text/css\">en-hilight { background-color: rgb(255,255,0) }</style>"); content.prepend("<style> img { height:auto; width:auto; max-height:auto; max-width:100%; }</style>"); content.prepend("<head><meta http-equiv=\"content-type\" content=\"text-html; charset=utf-8\"></head>"); content.prepend("<html>"); content.append("</html>"); if (!formatError && !readOnly) { NotebookTable ntable; qint32 notebookLid = ntable.getLid(note.notebookGuid); if (ntable.isReadOnly(notebookLid)) readOnly = true; } if (note.__isset.active && !note.active) readOnly = true; return content; }