2 * This file is part of NixNote/NeighborNote
\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 (fileInfo.completeSuffix().equalsIgnoreCase("txt"))
\r
69 return importTextFile();
\r
70 return importAttachment();
\r
75 //********************************************************
\r
76 //* Import text files
\r
77 //********************************************************
\r
78 public boolean importTextFile() {
\r
79 QFile file = new QFile(fileName);
\r
80 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly))) {
\r
81 // If we can't get to the file, it is probably locked. We'll try again later.
\r
82 logger.log(logger.LOW, "Unable to save externally edited file - locked. Saving for later.");
\r
85 QByteArray binData = file.readAll();
\r
87 if (binData.size() == 0) {
\r
88 // If we can't get to the file, it is probably locked. We'll try again later.
\r
89 logger.log(logger.LOW, "Unable to save externally edited file - zero size. Saving for later.");
\r
93 String fileData =binData.toString();
\r
95 // Fix \r\n & \n and turn inte HTML
\r
96 QWebPage page = new QWebPage();
\r
97 page.mainFrame().setContent(binData);
\r
98 fileData = page.mainFrame().toHtml();
\r
99 fileData = fileData.replace("\n", "<br>\n");
\r
101 noteString = new String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
\r
102 "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">\n" +
\r
103 "<en-note>\n<br clear=\"none\" />"+fileData+"</en-note>");
\r
105 noteString = fileData;
\r
107 newNote.setAttributes(new NoteAttributes());
\r
112 //********************************************************
\r
113 //* Import an image
\r
114 //********************************************************
\r
115 public boolean importAttachment() {
\r
116 QFile file = new QFile(fileName);
\r
117 if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly))) {
\r
118 // If we can't get to the file, it is probably locked. We'll try again later.
\r
119 logger.log(logger.LOW, "Unable to save externally edited file - locked. Saving for later.");
\r
122 QByteArray binData = file.readAll();
\r
124 if (binData.size() == 0) {
\r
125 // If we can't get to the file, it is probably locked. We'll try again later.
\r
126 logger.log(logger.LOW, "Unable to save externally edited file - zero size. Saving for later.");
\r
131 newNote.setAttributes(new NoteAttributes());
\r
133 // Start building the resource itself
\r
134 StringBuffer buffer = new StringBuffer();
\r
135 buffer.append("<html><head></head><body>\n");
\r
139 // If we have an image
\r
140 if (isImage(fileInfo.completeSuffix())) {
\r
141 String mimeType = "image/" +fileInfo.completeSuffix();
\r
142 if (mimeType.equals("image/jpg"))
\r
143 mimeType = "image/jpeg";
\r
144 newRes = createResource(mimeType, false);
\r
146 buffer.append("<img src=\"" +fileName);
\r
147 buffer.append("\" en-tag=\"en-media\" type=\"" + mimeType +"\""
\r
148 +" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\""
\r
149 +" guid=\"" +newRes.getGuid() +"\">");
\r
151 // We have an attachment, not an image.
\r
154 String mimeType = "application/" +fileInfo.completeSuffix();
\r
155 newRes = createResource(mimeType, false);
\r
156 newRes.getAttributes().setFileName(fileInfo.fileName());
\r
158 String icon = findIcon(fileInfo.completeSuffix());
\r
159 String imageURL = FileUtils.toFileURLString(Global.getFileManager().getImageDirFile(icon));
\r
160 buffer.append("<a en-tag=\"en-media\" guid=\"" +newRes.getGuid()+"\" ");
\r
161 buffer.append("type=\"" + mimeType + "\" href=\"nnres://" + fileName +"\" hash=\""+Global.byteArrayToHexString(newRes.getData().getBodyHash()) +"\" >");
\r
162 buffer.append("<img src=\"" + imageURL +"\" title=\"" +newRes.getAttributes().getFileName());
\r
163 buffer.append("\">");
\r
164 buffer.append("</a>");
\r
166 buffer.append("</body></html>");
\r
168 content = buffer.toString();
\r
169 noteString = buffer.toString();
\r
170 newNote.setContent(content);
\r
171 newNote.setResources(new ArrayList<Resource>());
\r
172 newNote.getResources().add(newRes);
\r
173 newNote.setResourcesIsSet(true);
\r
179 //********************************************************
\r
180 //* Check if we found an image
\r
181 //********************************************************
\r
182 // Check if the account supports this type of attachment
\r
183 private boolean isImage(String type) {
\r
184 if (type.equalsIgnoreCase("JPG"))
\r
186 if (type.equalsIgnoreCase("JPEG"))
\r
188 if (type.equalsIgnoreCase("PNG"))
\r
190 if (type.equalsIgnoreCase("GIF"))
\r
192 if (!Global.isPremium())
\r
194 if (type.equalsIgnoreCase("XPM"))
\r
196 if (type.equalsIgnoreCase("BMP"))
\r
202 //********************************************************
\r
203 //* Build an empty note
\r
204 //********************************************************
\r
205 private void buildEmptyNote() {
\r
206 Calendar currentTime = new GregorianCalendar();
\r
207 String baseNote = new String("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
\r
208 "<!DOCTYPE en-note SYSTEM \"http://xml.evernote.com/pub/enml2.dtd\">\n" +
\r
209 "<en-note>\n<br clear=\"none\" /></en-note>");
\r
210 Long l = new Long(currentTime.getTimeInMillis());
\r
212 while (prevTime==l) {
\r
213 currentTime = new GregorianCalendar();
\r
214 l=currentTime.getTimeInMillis();
\r
217 String randint = new String(Long.toString(l));
\r
219 newNote = new Note();
\r
220 newNote.setUpdateSequenceNum(0);
\r
221 newNote.setGuid(randint);
\r
222 newNote.setTitle(fileName);
\r
223 newNote.setContent(baseNote);
\r
224 newNote.setDeleted(0);
\r
225 int cdate = fileInfo.created().toTime_t();
\r
226 int mdate = fileInfo.lastModified().toTime_t();
\r
227 newNote.setCreated((long)cdate*1000);
\r
228 newNote.setUpdated((long)mdate*1000);
\r
229 newNote.setActive(true);
\r
230 NoteAttributes na = new NoteAttributes();
\r
231 na.setLatitude(0.0);
\r
232 na.setLongitude(0.0);
\r
233 na.setAltitude(0.0);
\r
235 //********************************************************
\r
236 //* Check valid file types
\r
237 //********************************************************
\r
238 public boolean isValidType() {
\r
239 if (!checkFileAttachmentSize(fileName))
\r
243 //**************************************************************
\r
244 //* Check the file attachment to be sure it isn't over 25 mb
\r
245 //**************************************************************
\r
246 private boolean checkFileAttachmentSize(String url) {
\r
247 QFile resourceFile = new QFile(fileName);
\r
248 resourceFile.open(new QIODevice.OpenMode(
\r
249 QIODevice.OpenModeFlag.ReadOnly));
\r
250 long size = resourceFile.size();
\r
251 resourceFile.close();
\r
252 size = size / 1024 / 1024;
\r
253 if (size < 50 && Global.isPremium())
\r
260 //********************************************************
\r
261 //* Build a new resource
\r
262 //********************************************************
\r
263 private Resource createResource(String mime, boolean attachment) {
\r
264 QFile resourceFile;
\r
265 resourceFile = new QFile(fileName);
\r
266 resourceFile.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadOnly));
\r
267 byte[] fileData = resourceFile.readAll().toByteArray();
\r
268 resourceFile.close();
\r
269 if (fileData.length == 0)
\r
273 md = MessageDigest.getInstance("MD5");
\r
274 md.update(fileData);
\r
275 byte[] hash = md.digest();
\r
277 Resource r = new Resource();
\r
278 Calendar time = new GregorianCalendar();
\r
279 Long l = time.getTimeInMillis();
\r
281 while (l==prevTime) {
\r
282 time = new GregorianCalendar();
\r
283 l=time.getTimeInMillis();
\r
285 r.setGuid(new Long(l).toString());
\r
286 r.setNoteGuid(newNote.getGuid());
\r
289 r.setUpdateSequenceNum(0);
\r
290 r.setWidth((short) 0);
\r
291 r.setHeight((short) 0);
\r
292 r.setDuration((short) 0);
\r
294 Data d = new Data();
\r
295 d.setBody(fileData);
\r
296 d.setBodyIsSet(true);
\r
297 d.setBodyHash(hash);
\r
298 d.setBodyHashIsSet(true);
\r
300 d.setSize(fileData.length);
\r
302 ResourceAttributes a = new ResourceAttributes();
\r
304 a.setAltitudeIsSet(false);
\r
306 a.setLongitudeIsSet(false);
\r
308 a.setLatitudeIsSet(false);
\r
309 a.setCameraMake("");
\r
310 a.setCameraMakeIsSet(false);
\r
311 a.setCameraModel("");
\r
312 a.setCameraModelIsSet(false);
\r
313 a.setAttachment(attachment);
\r
314 a.setAttachmentIsSet(true);
\r
315 a.setClientWillIndex(false);
\r
316 a.setClientWillIndexIsSet(true);
\r
318 a.setRecoTypeIsSet(false);
\r
319 a.setSourceURLIsSet(false);
\r
321 a.setTimestampIsSet(false);
\r
322 a.setFileName(fileInfo.fileName());
\r
323 a.setFileNameIsSet(true);
\r
324 r.setAttributes(a);
\r
326 conn.getNoteTable().noteResourceTable.saveNoteResource(r, true);
\r
328 } catch (NoSuchAlgorithmException e1) {
\r
329 e1.printStackTrace();
\r
334 //********************************************************
\r
336 //********************************************************
\r
337 public void setFileInfo(QFileInfo f) {
\r
340 //********************************************************
\r
342 //********************************************************
\r
343 public void setFileName(String f) {
\r
346 //********************************************************
\r
347 //* Get file contents
\r
348 //********************************************************
\r
349 public String getContent() {
\r
352 //********************************************************
\r
353 //* Return the new note
\r
354 //********************************************************
\r
355 public Note getNote() {
\r
358 //********************************************************
\r
359 //* Get just the content of the new note
\r
360 //********************************************************
\r
361 public String getNoteContent() {
\r
366 * find the appropriate icon for an attachment
\r
367 * NFC TODO: duplicate of {@link NeverNote#findIcon(String)}
\r
369 private String findIcon(String appl) {
\r
370 appl = appl.toLowerCase();
\r
371 String relativePath = appl + ".png";
\r
372 File f = Global.getFileManager().getImageDirFile(relativePath);
\r
374 return relativePath;
\r
376 return "attachment.png";
\r