/* * This file is part of NixNote * Copyright 2011 Randy Baumgarte * * This file may be licensed under the terms of of the * GNU General Public License Version 2 (the ``GPL''). * * Software distributed under the License is distributed * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either * express or implied. See the GPL for the specific language * governing rights and limitations. * * You should have received a copy of the GPL along with this * program. If not, go to http://www.gnu.org/licenses/gpl.html * or write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ package cx.fbn.nevernote.xml; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.xml.bind.DatatypeConverter; import com.evernote.edam.type.Data; import com.evernote.edam.type.Note; import com.evernote.edam.type.NoteAttributes; import com.evernote.edam.type.Resource; import com.evernote.edam.type.ResourceAttributes; import com.evernote.edam.type.Tag; import com.trolltech.qt.core.QByteArray; import com.trolltech.qt.core.QFile; import com.trolltech.qt.core.QIODevice; import com.trolltech.qt.core.QUuid; import com.trolltech.qt.xml.QXmlStreamReader; import cx.fbn.nevernote.sql.DatabaseConnection; import cx.fbn.nevernote.utilities.ApplicationLogger; public class ImportEnex { public int lastError; private String errorMessage; private String fileName; DatabaseConnection conn; QXmlStreamReader reader; private Note note; public int highUpdateSequenceNumber; public long lastSequenceDate; private final ApplicationLogger logger; private String notebookGuid; public final boolean importTags = false; public final boolean importNotebooks = false; private String newGuid; List<Tag> tags; public boolean createNewTags; public ImportEnex(DatabaseConnection c, boolean full) { logger = new ApplicationLogger("import.log"); conn = c; tags = conn.getTagTable().getAll(); createNewTags = true; } public void importData(String f) { fileName = f; errorMessage = ""; lastError = 0; errorMessage = ""; QFile xmlFile = new QFile(fileName); if (!xmlFile.open(QIODevice.OpenModeFlag.ReadOnly)) { lastError = 16; errorMessage = "Cannot open file."; } reader = new QXmlStreamReader(xmlFile); while (!reader.atEnd()) { reader.readNext(); if (reader.hasError()) { errorMessage = reader.errorString(); logger.log(logger.LOW, "************************* ERROR READING FILE " +reader.errorString()); lastError = 16; return; } if (reader.name().equalsIgnoreCase("note") && reader.isStartElement()) { processNoteNode(); note.setUpdateSequenceNum(0); if (notebookGuid != null) note.setNotebookGuid(notebookGuid); for (int i=0; i<note.getResourcesSize(); i++) { note.getResources().get(i).setUpdateSequenceNum(0); } note.setActive(true); if (note.getUpdated() == 0) { note.setUpdated(note.getCreated()); } conn.getNoteTable().addNote(note, true); } } xmlFile.close(); } private void processNoteNode() { note = new Note(); newGuid = QUuid.createUuid().toString().replace("{", "").replace("}", ""); note.setGuid(newGuid); note.setResources(new ArrayList<Resource>()); boolean atEnd = false; while(!atEnd) { if (reader.name().equalsIgnoreCase("title")) note.setTitle(textValue()); if (reader.name().equalsIgnoreCase("Created")) note.setCreated(datetimeValue()); if (reader.name().equalsIgnoreCase("updated")) note.setCreated(datetimeValue()); if (reader.name().equalsIgnoreCase("Content")) note.setContent(textValue()); if (reader.name().equalsIgnoreCase("tag") && createNewTags) { String tag = textValue(); Tag noteTag = null; boolean found=false; for (int i=0; i<tags.size(); i++) { if (tags.get(i).getName().equalsIgnoreCase(tag)) { found=true; noteTag = tags.get(i); i=tags.size(); } } if (!found) { noteTag = new Tag(); noteTag.setName(tag); String tagGuid = QUuid.createUuid().toString().replace("{", "").replace("}", ""); noteTag.setGuid(tagGuid); noteTag.setName(tag); tags.add(noteTag); conn.getTagTable().addTag(noteTag, true); } note.addToTagNames(noteTag.getName()); note.addToTagGuids(noteTag.getGuid()); } if (reader.name().equalsIgnoreCase("note-attributes")) note.setAttributes(processNoteAttributes()); if (reader.name().equalsIgnoreCase("resource")) { note.getResources().add(processResource()); } reader.readNext(); if (reader.name().equalsIgnoreCase("note") && reader.isEndElement()) atEnd = true; } return; } private Resource processResource() { Resource resource = new Resource(); boolean atEnd = false; while(!atEnd) { if (reader.isStartElement() && reader.name().equalsIgnoreCase("resource")) { String newResGuid = QUuid.createUuid().toString().replace("{", "").replace("}", ""); resource.setGuid(newResGuid); resource.setNoteGuid(this.newGuid); } if (reader.name().equalsIgnoreCase("mime")) resource.setMime(textValue()); if (reader.name().equalsIgnoreCase("height")) resource.setHeight(shortValue()); if (reader.name().equalsIgnoreCase("width")) resource.setWidth(shortValue()); if (reader.name().equalsIgnoreCase("data")) resource.setData(processData("data")); if (reader.name().equalsIgnoreCase("resource-attributes")) resource.setAttributes(processResourceAttributes()); if (reader.name().equalsIgnoreCase("recognition")) resource.setRecognition(processRecognition()); reader.readNext(); if (reader.name().equalsIgnoreCase("resource") && reader.isEndElement()) atEnd = true; } if (resource.getAttributes() == null) resource.setAttributes(new ResourceAttributes()); conn.getNoteTable().noteResourceTable.updateNoteResource(resource, true); return resource; } private Data processData(String nodeName) { Data data = new Data(); boolean atEnd = false; while(!atEnd) { if (reader.isStartElement()) { try { byte[] b = textValue().getBytes(); // data binary if (b.length > 0) { QByteArray hexData = new QByteArray(b); String hexString = hexData.toString(); data.setBody(DatatypeConverter.parseBase64Binary(hexString)); MessageDigest md; try { md = MessageDigest.getInstance("MD5"); md.update(data.getBody()); data.setBodyHash(md.digest()); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } }} catch (Exception e) {}; } if (reader.name().equalsIgnoreCase(nodeName) && reader.isEndElement()) atEnd = true; else reader.readNext(); } return data; } private NoteAttributes processNoteAttributes() { NoteAttributes attributes = new NoteAttributes(); boolean atEnd = false; while(!atEnd) { if (reader.isStartElement()) { if (reader.name().equalsIgnoreCase("source-url")) attributes.setSourceURL(textValue()); if (reader.name().equalsIgnoreCase("source")) attributes.setSource(textValue()); if (reader.name().equalsIgnoreCase("longitude")) attributes.setLongitude(doubleValue()); if (reader.name().equalsIgnoreCase("latitude")) attributes.setLatitude(doubleValue()); if (reader.name().equalsIgnoreCase("altitude")) attributes.setAltitude(doubleValue()); if (reader.name().equalsIgnoreCase("author")) attributes.setAuthor(textValue()); if (reader.name().equalsIgnoreCase("subject-date")) attributes.setSubjectDate(datetimeValue()); } reader.readNext(); if (reader.name().equalsIgnoreCase("note-attributes") && reader.isEndElement()) atEnd = true; } return attributes; } private Data processRecognition() { Data reco = new Data(); reco.setBody(textValue().getBytes()); MessageDigest md; try { md = MessageDigest.getInstance("MD5"); md.update(reco.getBody()); reco.setBodyHash(md.digest()); reco.setSize(reco.getBody().length); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } return reco; } private ResourceAttributes processResourceAttributes() { ResourceAttributes attributes = new ResourceAttributes(); boolean atEnd = false; while(!atEnd) { if (reader.isStartElement()) { if (reader.name().equalsIgnoreCase("camera-model")) attributes.setCameraModel(textValue()); if (reader.name().equalsIgnoreCase("file-name")) attributes.setFileName(textValue()); if (reader.name().equalsIgnoreCase("reco-type")) attributes.setRecoType(textValue()); if (reader.name().equalsIgnoreCase("camera-make")) attributes.setCameraMake(textValue()); if (reader.name().equalsIgnoreCase("source-url")) attributes.setSourceURL(textValue()); if (reader.name().equalsIgnoreCase("Altitude")) attributes.setAltitude(doubleValue()); if (reader.name().equalsIgnoreCase("Longitude")) attributes.setLongitude(doubleValue()); if (reader.name().equalsIgnoreCase("Latitude")) attributes.setLatitude(doubleValue()); if (reader.name().equalsIgnoreCase("Timestamp")) attributes.setTimestamp(longValue()); if (reader.name().equalsIgnoreCase("Attachment")) attributes.setAttachment(booleanValue()); if (reader.name().equalsIgnoreCase("ClientWillIndex")) attributes.setClientWillIndex(booleanValue()); } reader.readNext(); if (reader.name().equalsIgnoreCase("resource-attributes") && reader.isEndElement()) atEnd = true; } return attributes; } private String textValue() { return reader.readElementText(); } private long longValue() { return new Long(textValue()); } private long datetimeValue() { Date d; String time = textValue(); String year = time.substring(0,4); String month = time.substring(4,6); String day = time.substring(6,8); String hour = time.substring(9,11); String minute = time.substring(11,13); String second = time.substring(13,15); DateFormat dfm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); try { d = dfm.parse(year +"-" +month +"-" +day +" " +hour +":" +minute +":" +second); return d.getTime(); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } return 0; } private boolean booleanValue() { String value = textValue(); if (value.equalsIgnoreCase("true")) return true; else return false; } private short shortValue() { return new Short(textValue()); } public void setNotebookGuid(String g) { notebookGuid = g; } public String getErrorMessage() { return errorMessage; } private double doubleValue() { return new Double(textValue()); } }