/*
* This file is part of NixNote
* Copyright 2009 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.utilities;
import java.io.File;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
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.trolltech.qt.core.QByteArray;
import com.trolltech.qt.core.QFile;
import com.trolltech.qt.core.QFileInfo;
import com.trolltech.qt.core.QIODevice;
import com.trolltech.qt.webkit.QWebPage;
import cx.fbn.nevernote.Global;
import cx.fbn.nevernote.NeverNote;
import cx.fbn.nevernote.sql.DatabaseConnection;
public class FileImporter {
private final ApplicationLogger logger;
private String fileName;
private String content;
private QFileInfo fileInfo;
private Note newNote;
private String noteString;
private final DatabaseConnection conn;
public FileImporter(ApplicationLogger l, DatabaseConnection c) {
logger = l;
conn = c;
}
//********************************************************
//* Begin to import the file
//********************************************************
public boolean importFile() {
if (fileInfo.isFile()) {
if (fileInfo.completeSuffix().equalsIgnoreCase("txt"))
return importTextFile();
return importAttachment();
}
return false;
}
//********************************************************
//* Import text files
//********************************************************
public boolean importTextFile() {
QFile file = new QFile(fileName);
if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly))) {
// If we can't get to the file, it is probably locked. We'll try again later.
logger.log(logger.LOW, "Unable to save externally edited file - locked. Saving for later.");
return false;
}
QByteArray binData = file.readAll();
file.close();
if (binData.size() == 0) {
// If we can't get to the file, it is probably locked. We'll try again later.
logger.log(logger.LOW, "Unable to save externally edited file - zero size. Saving for later.");
return false;
}
String fileData =binData.toString();
// Fix \r\n & \n and turn inte HTML
QWebPage page = new QWebPage();
page.mainFrame().setContent(binData);
fileData = page.mainFrame().toHtml();
fileData = fileData.replace("\n", "<br>\n");
noteString = new String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">\n" +
"<en-note>\n<br clear=\"none\" />"+fileData+"</en-note>");
noteString = fileData;
buildEmptyNote();
newNote.setAttributes(new NoteAttributes());
return true;
}
//********************************************************
//* Import an image
//********************************************************
public boolean importAttachment() {
QFile file = new QFile(fileName);
if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly))) {
// If we can't get to the file, it is probably locked. We'll try again later.
logger.log(logger.LOW, "Unable to save externally edited file - locked. Saving for later.");
return false;
}
QByteArray binData = file.readAll();
file.close();
if (binData.size() == 0) {
// If we can't get to the file, it is probably locked. We'll try again later.
logger.log(logger.LOW, "Unable to save externally edited file - zero size. Saving for later.");
return false;
}
buildEmptyNote();
newNote.setAttributes(new NoteAttributes());
// Start building the resource itself
StringBuffer buffer = new StringBuffer();
buffer.append("<html><head></head><body>\n");
Resource newRes;
// If we have an image
if (isImage(fileInfo.completeSuffix())) {
String mimeType = "image/" +fileInfo.completeSuffix();
if (mimeType.equals("image/jpg"))
mimeType = "image/jpeg";
newRes = createResource(mimeType, false);
buffer.append("<img src=\"" +fileName);
buffer.append("\" en-tag=\"en-media\" type=\"" + mimeType +"\""
+" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""
+" guid=\"" +newRes.getGuid() +"\">");
} else {
// We have an attachment, not an image.
String mimeType = "application/" +fileInfo.completeSuffix();
newRes = createResource(mimeType, false);
newRes.getAttributes().setFileName(fileInfo.fileName());
String icon = findIcon(fileInfo.completeSuffix());
String imageURL = FileUtils.toFileURLString(Global.getFileManager().getImageDirFile(icon));
buffer.append("<a en-tag=\"en-media\" guid=\"" +newRes.getGuid()+"\" ");
buffer.append("type=\"" + mimeType + "\" href=\"nnres://" + fileName +"\" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\" >");
buffer.append("<img src=\"" + imageURL +"\" title=\"" +newRes.getAttributes().getFileName());
buffer.append("\">");
buffer.append("</a>");
}
buffer.append("</body></html>");
content = buffer.toString();
noteString = buffer.toString();
newNote.setContent(content);
newNote.setResources(new ArrayList<Resource>());
newNote.getResources().add(newRes);
newNote.setResourcesIsSet(true);
return true;
}
//********************************************************
//* Check if we found an image
//********************************************************
// Check if the account supports this type of attachment
private boolean isImage(String type) {
if (type.equalsIgnoreCase("JPG"))
return true;
if (type.equalsIgnoreCase("JPEG"))
return true;
if (type.equalsIgnoreCase("PNG"))
return true;
if (type.equalsIgnoreCase("GIF"))
return true;
if (!Global.isPremium())
return false;
if (type.equalsIgnoreCase("XPM"))
return true;
if (type.equalsIgnoreCase("BMP"))
return true;
return false;
}
//********************************************************
//* Build an empty note
//********************************************************
private void buildEmptyNote() {
Calendar currentTime = new GregorianCalendar();
String baseNote = new String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">\n" +
"<en-note>\n<br clear=\"none\" /></en-note>");
Long l = new Long(currentTime.getTimeInMillis());
long prevTime = l;
while (prevTime==l) {
currentTime = new GregorianCalendar();
l=currentTime.getTimeInMillis();
}
String randint = new String(Long.toString(l));
newNote = new Note();
newNote.setUpdateSequenceNum(0);
newNote.setGuid(randint);
newNote.setTitle(fileName);
newNote.setContent(baseNote);
newNote.setDeleted(0);
int cdate = fileInfo.created().toTime_t();
int mdate = fileInfo.lastModified().toTime_t();
newNote.setCreated((long)cdate*1000);
newNote.setUpdated((long)mdate*1000);
newNote.setActive(true);
NoteAttributes na = new NoteAttributes();
na.setLatitude(0.0);
na.setLongitude(0.0);
na.setAltitude(0.0);
}
//********************************************************
//* Check valid file types
//********************************************************
public boolean isValidType() {
if (!checkFileAttachmentSize(fileName))
return false;
return true;
}
//**************************************************************
//* Check the file attachment to be sure it isn't over 25 mb
//**************************************************************
private boolean checkFileAttachmentSize(String url) {
QFile resourceFile = new QFile(fileName);
resourceFile.open(new QIODevice.OpenMode(
QIODevice.OpenModeFlag.ReadOnly));
long size = resourceFile.size();
resourceFile.close();
size = size / 1024 / 1024;
if (size < 50 && Global.isPremium())
return true;
if (size < 25)
return true;
return false;
}
//********************************************************
//* Build a new resource
//********************************************************
private Resource createResource(String mime, boolean attachment) {
QFile resourceFile;
resourceFile = new QFile(fileName);
resourceFile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly));
byte[] fileData = resourceFile.readAll().toByteArray();
resourceFile.close();
if (fileData.length == 0)
return null;
MessageDigest md;
try {
md = MessageDigest.getInstance("MD5");
md.update(fileData);
byte[] hash = md.digest();
Resource r = new Resource();
Calendar time = new GregorianCalendar();
Long l = time.getTimeInMillis();
long prevTime = l;
while (l==prevTime) {
time = new GregorianCalendar();
l=time.getTimeInMillis();
}
r.setGuid(new Long(l).toString());
r.setNoteGuid(newNote.getGuid());
r.setMime(mime);
r.setActive(true);
r.setUpdateSequenceNum(0);
r.setWidth((short) 0);
r.setHeight((short) 0);
r.setDuration((short) 0);
Data d = new Data();
d.setBody(fileData);
d.setBodyIsSet(true);
d.setBodyHash(hash);
d.setBodyHashIsSet(true);
r.setData(d);
d.setSize(fileData.length);
ResourceAttributes a = new ResourceAttributes();
a.setAltitude(0);
a.setAltitudeIsSet(false);
a.setLongitude(0);
a.setLongitudeIsSet(false);
a.setLatitude(0);
a.setLatitudeIsSet(false);
a.setCameraMake("");
a.setCameraMakeIsSet(false);
a.setCameraModel("");
a.setCameraModelIsSet(false);
a.setAttachment(attachment);
a.setAttachmentIsSet(true);
a.setClientWillIndex(false);
a.setClientWillIndexIsSet(true);
a.setRecoType("");
a.setRecoTypeIsSet(false);
a.setSourceURLIsSet(false);
a.setTimestamp(0);
a.setTimestampIsSet(false);
a.setFileName(fileInfo.fileName());
a.setFileNameIsSet(true);
r.setAttributes(a);
conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);
return r;
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
}
return null;
}
//********************************************************
//* set file name
//********************************************************
public void setFileInfo(QFileInfo f) {
fileInfo = f;
}
//********************************************************
//* Set file name
//********************************************************
public void setFileName(String f) {
fileName = f;
}
//********************************************************
//* Get file contents
//********************************************************
public String getContent() {
return content;
}
//********************************************************
//* Return the new note
//********************************************************
public Note getNote() {
return newNote;
}
//********************************************************
//* Get just the content of the new note
//********************************************************
public String getNoteContent() {
return noteString;
}
/**
* find the appropriate icon for an attachment
* NFC TODO: duplicate of {@link NeverNote#findIcon(String)}
*/
private String findIcon(String appl) {
appl = appl.toLowerCase();
String relativePath = appl + ".png";
File f = Global.getFileManager().getImageDirFile(relativePath);
if (f.exists()) {
return relativePath;
}
return "attachment.png";
}
}