1
2
3
4
5
6
7
8 package com.buckosoft.PicMan.business;
9
10 import java.io.File;
11 import java.text.ParseException;
12 import java.text.SimpleDateFormat;
13 import java.util.Date;
14 import java.util.LinkedList;
15 import java.util.List;
16
17 import org.apache.commons.logging.Log;
18 import org.apache.commons.logging.LogFactory;
19 import org.dom4j.Document;
20
21 import com.buckosoft.PicMan.business.util.CopyFile;
22 import com.buckosoft.PicMan.business.util.MD5SumUpdater;
23 import com.buckosoft.PicMan.dom.ImportAnalyzeDom;
24 import com.buckosoft.PicMan.dom.ImportPicsDom;
25 import com.buckosoft.PicMan.domain.Pic;
26 import com.buckosoft.PicMan.domain.Root;
27 import com.buckosoft.PicMan.image.PicReader;
28 import com.drew.imaging.ImageMetadataReader;
29 import com.drew.metadata.Metadata;
30 import com.drew.metadata.exif.ExifIFD0Directory;
31
32
33
34
35
36
37 public class PicImporterImpl implements PicImporter {
38 protected final Log log = LogFactory.getLog(getClass());
39
40 private PicManFacade pmf;
41 private List<String> picExtensions;
42 private byte[] buf = new byte[4096];
43
44
45
46
47
48 public void setPicMan(PicManFacade pmf) {
49 this.pmf = pmf;
50 }
51
52
53
54
55 public List<File> getPicNamesToImport() {
56
57 picExtensions = pmf.getDB().getPicExtensions();
58 LinkedList<File> list = new LinkedList<File>();
59 File f = new File(pmf.getDB().getSystem().getImportDirectory());
60 File[] files = f.listFiles();
61 if (files == null) {
62 return(list);
63 }
64 for (int i=0; i<files.length; i++) {
65 File file = files[i];
66 String s = file.getName();
67 if (s.length() < 4)
68 continue;
69 String t = s.substring(s.length()-3);
70 boolean match = false;
71 for (String pe : picExtensions) {
72 if (t.compareToIgnoreCase(pe) == 0) {
73 match = true;
74 break;
75 }
76 }
77 if (match) {
78 list.add(file);
79 log.info("Add: " + s);
80 }
81 }
82 return list;
83 }
84
85
86
87
88 public Document importPic(int rid, String odir, String iname, String oname) {
89 boolean success = false;
90 String is;
91 if (rid == -1) {
92 is = pmf.getDB().getSystem().getImportDirectory() + "/" + iname;
93 File fromFile = new File(is);
94 try {
95 success = fromFile.delete();
96 } catch (Exception e) {
97 return(ImportPicsDom.createDocument(iname, 1, "Failed to delete file: " + e.getLocalizedMessage()));
98 }
99 return(ImportPicsDom.createDocument(iname, 0, "success"));
100 }
101 Root root = pmf.getDB().getRoot(rid);
102 is = pmf.getDB().getSystem().getImportDirectory() + "/" + iname;
103 File fromFile = new File(is);
104 File toFile = new File(root.getPath() + "/" + odir + "/" + oname + ".jpg");
105 if (!fromFile.canRead())
106 return(ImportPicsDom.createDocument(iname, 1, "Input file doesn't exist"));
107 if (toFile.exists())
108 return(ImportPicsDom.createDocument(iname, 1, "Output file exists"));
109 File toDir = new File(root.getPath() + "/" + odir);
110 if (!toDir.isDirectory()) {
111 try {
112 toDir.mkdirs();
113 } catch (Exception e) {
114 return(ImportPicsDom.createDocument(iname, 1, "Failed to make output directory: " + e.getLocalizedMessage()));
115 }
116 }
117 try {
118 CopyFile.copyFile(fromFile, toFile, buf);
119 } catch(Exception e) {
120 return(ImportPicsDom.createDocument(iname, 1, "Failed to copy file: " + e.getLocalizedMessage()));
121 }
122 toFile.setReadOnly();
123 Pic pic = pmf.getDB().getPic(oname);
124 if (pic == null) {
125 log.error("Can't find newly imported pic '" + oname + "'");
126 } else {
127 MD5SumUpdater.calculateMD5Sum(pmf, pic);
128 log.debug("md5sum for " + pic.getName() + " = " + pic.getMd5());
129 pmf.getDB().updatePic(pic);
130 }
131 try {
132 success = fromFile.delete();
133 } catch (Exception e) {
134 return(ImportPicsDom.createDocument(iname, 1, "Failed to delete file: " + e.getLocalizedMessage()));
135
136 }
137 if (!success) {
138 try {
139 Thread.sleep(1000);
140 success = fromFile.delete();
141 } catch (Exception e) {
142 return(ImportPicsDom.createDocument(iname, 1, "Failed to delete file: " + e.getLocalizedMessage()));
143 }
144
145 }
146 if (!success) {
147 try {
148 Thread.sleep(3000);
149 success = fromFile.delete();
150 if (!success) {
151 fromFile = null;
152 success = new File(is).delete();
153 }
154 } catch (Exception e) {
155 return(ImportPicsDom.createDocument(iname, 1, "Failed to delete file: " + e.getLocalizedMessage()));
156 }
157
158 }
159 if (!success)
160 return(ImportPicsDom.createDocument(iname, 1, "Failed to delete file."));
161
162 return(ImportPicsDom.createDocument(iname, 0, "success"));
163 }
164
165 @Override
166 public Document analyzePic(String fname, String customDate) {
167 Pic iPic = new Pic(true, fname);
168 List<Pic> pics = checkForDuplicatePics(fname);
169 PossibleDates pds = getPossibleDates(iPic, customDate);
170 return(ImportAnalyzeDom.createDocument(pics, pds));
171 }
172
173 private List<Pic> checkForDuplicatePics(String fname) {
174 Pic pic = new Pic(true, fname);
175 MD5SumUpdater.calculateMD5Sum(pmf, pic);
176 log.info("checkForDups: " + fname + " -- " + pic.getMd5());
177 List<Pic> dups = pmf.getDB().getPicsByMD5Sum(pic.getMd5());
178 return(dups);
179 }
180
181 private SimpleDateFormat sdf = new SimpleDateFormat();
182
183 private PossibleDates getPossibleDates(Pic iPic, String customDate) {
184 PossibleDates pds = new PossibleDates();
185 if (customDate != null) {
186 try {
187 pds.setCustomDate(sdf.parse(customDate));
188 } catch (ParseException e) {
189 log.warn("Failed to parse customDate", e);
190 }
191 }
192 File f;
193 f = new File(PicReader.getFullPath(pmf, iPic));
194 if (f == null) {
195 log.warn("Can't find file " + PicReader.getFullPath(pmf, iPic));
196 return(pds);
197 } else {
198 pds.setFileDate(new Date(f.lastModified()));
199 }
200
201 Metadata metadata = null;
202 try {
203 metadata = ImageMetadataReader.readMetadata(f);
204
205 } catch (Throwable t) {
206 t.printStackTrace();
207 }
208 String s = null;
209 if (metadata != null) {
210 ExifIFD0Directory directory = metadata.getDirectory(ExifIFD0Directory.class);
211 try {
212 s = directory.getString(ExifIFD0Directory.TAG_DATETIME);
213 } catch (Exception e) {}
214
215
216
217
218
219
220
221
222
223
224 }
225 log.info("s = " + s);
226 if (s != null) {
227 SimpleDateFormat sdf = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
228 try {
229 pds.setTakenDate(sdf.parse(s));
230 log.info("Taken date: " + pds.getTakenDate());
231 } catch (ParseException e) {
232 log.warn("Failed to parse date", e);
233 }
234 }
235 return(pds);
236 }
237
238 public class PossibleDates {
239 Date takenDate = null;
240 Date fileDate = null;
241 Date customDate = null;
242
243
244
245 public Date getTakenDate() {
246 return takenDate;
247 }
248
249
250
251 public void setTakenDate(Date takenDate) {
252 this.takenDate = takenDate;
253 }
254
255
256
257 public Date getFileDate() {
258 return fileDate;
259 }
260
261
262
263 public void setFileDate(Date fileDate) {
264 this.fileDate = fileDate;
265 }
266
267
268
269 public Date getCustomDate() {
270 return customDate;
271 }
272
273
274
275 public void setCustomDate(Date customDate) {
276 this.customDate = customDate;
277 }
278
279 }
280
281 }