2 * This file is part of NeverNote
\r
3 * Copyright 2009 Randy Baumgarte
\r
5 * This file may be licensed under the terms of of the
\r
6 * GNU General Public License Version 2 (the ``GPL'').
\r
8 * Software distributed under the License is distributed
\r
9 * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
\r
10 * express or implied. See the GPL for the specific language
\r
11 * governing rights and limitations.
\r
13 * You should have received a copy of the GPL along with this
\r
14 * program. If not, go to http://www.gnu.org/licenses/gpl.html
\r
15 * or write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
\r
20 package cx.fbn.nevernote.utilities;
\r
22 import java.io.File;
\r
23 import java.security.MessageDigest;
\r
24 import java.security.NoSuchAlgorithmException;
\r
25 import java.util.ArrayList;
\r
26 import java.util.Calendar;
\r
27 import java.util.GregorianCalendar;
\r
29 import com.evernote.edam.type.Data;
\r
30 import com.evernote.edam.type.Note;
\r
31 import com.evernote.edam.type.NoteAttributes;
\r
32 import com.evernote.edam.type.Resource;
\r
33 import com.evernote.edam.type.ResourceAttributes;
\r
34 import com.trolltech.qt.core.QByteArray;
\r
35 import com.trolltech.qt.core.QFile;
\r
36 import com.trolltech.qt.core.QFileInfo;
\r
37 import com.trolltech.qt.core.QIODevice;
\r
38 import com.trolltech.qt.webkit.QWebPage;
\r
40 import cx.fbn.nevernote.Global;
\r
41 import cx.fbn.nevernote.NeverNote;
\r
42 import cx.fbn.nevernote.sql.DatabaseConnection;
\r
46 public class FileImporter {
\r
48 private final ApplicationLogger logger;
\r
49 private String fileName;
\r
50 private String content;
\r
51 private QFileInfo fileInfo;
\r
52 private Note newNote;
\r
53 private String noteString;
\r
54 private final DatabaseConnection conn;
\r
57 public FileImporter(ApplicationLogger l, DatabaseConnection c) {
\r
63 //********************************************************
\r
64 //* Begin to import the file
\r
65 //********************************************************
\r
66 public boolean importFile() {
\r
67 if (fileInfo.isFile()) {
\r
68 if (!validAttachment(fileInfo.completeSuffix()))
\r
70 if (fileInfo.completeSuffix().equalsIgnoreCase("txt"))
\r
71 return importTextFile();
\r
72 return importAttachment();
\r
77 //********************************************************
\r
78 //* Import text files
\r
79 //********************************************************
\r
80 public boolean importTextFile() {
\r
81 QFile file = new QFile(fileName);
\r
82 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly))) {
\r
83 // If we can't get to the file, it is probably locked. We'll try again later.
\r
84 logger.log(logger.LOW, "Unable to save externally edited file - locked. Saving for later.");
\r
87 QByteArray binData = file.readAll();
\r
89 if (binData.size() == 0) {
\r
90 // If we can't get to the file, it is probably locked. We'll try again later.
\r
91 logger.log(logger.LOW, "Unable to save externally edited file - zero size. Saving for later.");
\r
95 String fileData =binData.toString();
\r
97 // Fix \r\n & \n and turn inte HTML
\r
98 QWebPage page = new QWebPage();
\r
99 page.mainFrame().setContent(binData);
\r
100 fileData = page.mainFrame().toHtml();
\r
101 fileData = fileData.replace("\n", "<br>\n");
\r
103 noteString = new String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
\r
104 "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">\n" +
\r
105 "<en-note>\n<br clear=\"none\" />"+fileData+"</en-note>");
\r
107 noteString = fileData;
\r
109 newNote.setAttributes(new NoteAttributes());
\r
114 //********************************************************
\r
115 //* Import an image
\r
116 //********************************************************
\r
117 public boolean importAttachment() {
\r
118 QFile file = new QFile(fileName);
\r
119 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly))) {
\r
120 // If we can't get to the file, it is probably locked. We'll try again later.
\r
121 logger.log(logger.LOW, "Unable to save externally edited file - locked. Saving for later.");
\r
124 QByteArray binData = file.readAll();
\r
126 if (binData.size() == 0) {
\r
127 // If we can't get to the file, it is probably locked. We'll try again later.
\r
128 logger.log(logger.LOW, "Unable to save externally edited file - zero size. Saving for later.");
\r
133 newNote.setAttributes(new NoteAttributes());
\r
135 // Start building the resource itself
\r
136 StringBuffer buffer = new StringBuffer();
\r
137 buffer.append("<html><head></head><body>\n");
\r
141 // If we have an image
\r
142 if (isImage(fileInfo.completeSuffix())) {
\r
143 String mimeType = "image/" +fileInfo.completeSuffix();
\r
144 if (mimeType.equals("image/jpg"))
\r
145 mimeType = "image/jpeg";
\r
146 newRes = createResource(mimeType, false);
\r
148 buffer.append("<img src=\"" +fileName);
\r
149 buffer.append("\" en-tag=\"en-media\" type=\"" + mimeType +"\""
\r
150 +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""
\r
151 +" guid=\"" +newRes.getGuid() +"\">");
\r
153 // We have an attachment, not an image.
\r
156 String mimeType = "application/" +fileInfo.completeSuffix();
\r
157 newRes = createResource(mimeType, false);
\r
158 newRes.getAttributes().setFileName(fileInfo.fileName());
\r
160 String icon = findIcon(fileInfo.completeSuffix());
\r
161 String imageURL = FileUtils.toFileURLString(Global.getFileManager().getImageDirFile(icon));
\r
162 buffer.append("<a en-tag=\"en-media\" guid=\"" +newRes.getGuid()+"\" ");
\r
163 buffer.append("type=\"" + mimeType + "\" href=\"nnres://" + fileName +"\" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\" >");
\r
164 buffer.append("<img src=\"" + imageURL +"\" title=\"" +newRes.getAttributes().getFileName());
\r
165 buffer.append("\">");
\r
166 buffer.append("</a>");
\r
168 buffer.append("</body></html>");
\r
170 content = buffer.toString();
\r
171 noteString = buffer.toString();
\r
172 newNote.setContent(content);
\r
173 newNote.setResources(new ArrayList<Resource>());
\r
174 newNote.getResources().add(newRes);
\r
175 newNote.setResourcesIsSet(true);
\r
180 //********************************************************
\r
181 //* Check if we found a valid file type
\r
182 //********************************************************
\r
183 // Check if the account supports this type of attachment
\r
184 private boolean validAttachment(String type) {
\r
185 if (Global.isPremium())
\r
187 if (type.equalsIgnoreCase("JPG"))
\r
189 if (type.equalsIgnoreCase("PNG"))
\r
191 if (type.equalsIgnoreCase("GIF"))
\r
193 if (type.equalsIgnoreCase("MP3"))
\r
195 if (type.equalsIgnoreCase("WAV"))
\r
197 if (type.equalsIgnoreCase("AMR"))
\r
199 if (type.equalsIgnoreCase("PDF"))
\r
201 if (type.equalsIgnoreCase("TXT"))
\r
206 //********************************************************
\r
207 //* Check if we found an image
\r
208 //********************************************************
\r
209 // Check if the account supports this type of attachment
\r
210 private boolean isImage(String type) {
\r
211 if (type.equalsIgnoreCase("JPG"))
\r
213 if (type.equalsIgnoreCase("JPEG"))
\r
215 if (type.equalsIgnoreCase("PNG"))
\r
217 if (type.equalsIgnoreCase("GIF"))
\r
219 if (!Global.isPremium())
\r
221 if (type.equalsIgnoreCase("XPM"))
\r
223 if (type.equalsIgnoreCase("BMP"))
\r
229 //********************************************************
\r
230 //* Build an empty note
\r
231 //********************************************************
\r
232 private void buildEmptyNote() {
\r
233 Calendar currentTime = new GregorianCalendar();
\r
234 String baseNote = new String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
\r
235 "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">\n" +
\r
236 "<en-note>\n<br clear=\"none\" /></en-note>");
\r
237 Long l = new Long(currentTime.getTimeInMillis());
\r
239 while (prevTime==l) {
\r
240 currentTime = new GregorianCalendar();
\r
241 l=currentTime.getTimeInMillis();
\r
244 String randint = new String(Long.toString(l));
\r
246 newNote = new Note();
\r
247 newNote.setUpdateSequenceNum(0);
\r
248 newNote.setGuid(randint);
\r
249 newNote.setTitle(fileName);
\r
250 newNote.setContent(baseNote);
\r
251 newNote.setDeleted(0);
\r
252 int cdate = fileInfo.created().toTime_t();
\r
253 int mdate = fileInfo.lastModified().toTime_t();
\r
254 newNote.setCreated((long)cdate*1000);
\r
255 newNote.setUpdated((long)mdate*1000);
\r
256 newNote.setActive(true);
\r
257 NoteAttributes na = new NoteAttributes();
\r
258 na.setLatitude(0.0);
\r
259 na.setLongitude(0.0);
\r
260 na.setAltitude(0.0);
\r
262 //********************************************************
\r
263 //* Check valid file types
\r
264 //********************************************************
\r
265 public boolean isValidType() {
\r
266 if (!checkFileAttachmentSize(fileName))
\r
268 if (fileInfo.completeSuffix().equalsIgnoreCase("txt"))
\r
270 if (validAttachment(fileInfo.completeSuffix()))
\r
274 //**************************************************************
\r
275 //* Check the file attachment to be sure it isn't over 25 mb
\r
276 //**************************************************************
\r
277 private boolean checkFileAttachmentSize(String url) {
\r
278 QFile resourceFile = new QFile(fileName);
\r
279 resourceFile.open(new QIODevice.OpenMode(
\r
280 QIODevice.OpenModeFlag.ReadOnly));
\r
281 long size = resourceFile.size();
\r
282 resourceFile.close();
\r
283 size = size / 1024 / 1024;
\r
284 if (size < 50 && Global.isPremium())
\r
291 //********************************************************
\r
292 //* Build a new resource
\r
293 //********************************************************
\r
294 private Resource createResource(String mime, boolean attachment) {
\r
295 QFile resourceFile;
\r
296 resourceFile = new QFile(fileName);
\r
297 resourceFile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly));
\r
298 byte[] fileData = resourceFile.readAll().toByteArray();
\r
299 resourceFile.close();
\r
300 if (fileData.length == 0)
\r
304 md = MessageDigest.getInstance("MD5");
\r
305 md.update(fileData);
\r
306 byte[] hash = md.digest();
\r
308 Resource r = new Resource();
\r
309 Calendar time = new GregorianCalendar();
\r
310 Long l = time.getTimeInMillis();
\r
312 while (l==prevTime) {
\r
313 time = new GregorianCalendar();
\r
314 l=time.getTimeInMillis();
\r
316 r.setGuid(new Long(l).toString());
\r
317 r.setNoteGuid(newNote.getGuid());
\r
320 r.setUpdateSequenceNum(0);
\r
321 r.setWidth((short) 0);
\r
322 r.setHeight((short) 0);
\r
323 r.setDuration((short) 0);
\r
325 Data d = new Data();
\r
326 d.setBody(fileData);
\r
327 d.setBodyIsSet(true);
\r
328 d.setBodyHash(hash);
\r
329 d.setBodyHashIsSet(true);
\r
331 d.setSize(fileData.length);
\r
333 ResourceAttributes a = new ResourceAttributes();
\r
335 a.setAltitudeIsSet(false);
\r
337 a.setLongitudeIsSet(false);
\r
339 a.setLatitudeIsSet(false);
\r
340 a.setCameraMake("");
\r
341 a.setCameraMakeIsSet(false);
\r
342 a.setCameraModel("");
\r
343 a.setCameraModelIsSet(false);
\r
344 a.setAttachment(attachment);
\r
345 a.setAttachmentIsSet(true);
\r
346 a.setClientWillIndex(false);
\r
347 a.setClientWillIndexIsSet(true);
\r
349 a.setRecoTypeIsSet(false);
\r
350 a.setSourceURLIsSet(false);
\r
352 a.setTimestampIsSet(false);
\r
353 a.setFileName(fileInfo.fileName());
\r
354 a.setFileNameIsSet(true);
\r
355 r.setAttributes(a);
\r
357 conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);
\r
359 } catch (NoSuchAlgorithmException e1) {
\r
360 e1.printStackTrace();
\r
365 //********************************************************
\r
367 //********************************************************
\r
368 public void setFileInfo(QFileInfo f) {
\r
371 //********************************************************
\r
373 //********************************************************
\r
374 public void setFileName(String f) {
\r
377 //********************************************************
\r
378 //* Get file contents
\r
379 //********************************************************
\r
380 public String getContent() {
\r
383 //********************************************************
\r
384 //* Return the new note
\r
385 //********************************************************
\r
386 public Note getNote() {
\r
389 //********************************************************
\r
390 //* Get just the content of the new note
\r
391 //********************************************************
\r
392 public String getNoteContent() {
\r
397 * find the appropriate icon for an attachment
\r
398 * NFC TODO: duplicate of {@link NeverNote#findIcon(String)}
\r
400 private String findIcon(String appl) {
\r
401 appl = appl.toLowerCase();
\r
402 String relativePath = appl + ".png";
\r
403 File f = Global.getFileManager().getImageDirFile(relativePath);
\r
405 return relativePath;
\r
407 return "attachment.png";
\r