Wiki source code of LoadingGroovy

Last modified by Ludovic Dubost on 2009/10/18 22:11

Show last authors
1
2 import java.util.*;
3 import javax.mail.Folder;
4 import com.xpn.xwiki.doc.*;
5 import com.xpn.xwiki.*;
6 import com.xpn.xwiki.util.Util;
7 import java.io.*;
8 import javax.mail.*;
9
10 public class LoadRecruitmentContactGroovy {
11 def context;
12 def xwiki;
13 def protocol;
14 def server;
15 def user;
16 def pass;
17 def defaultUser;
18 def debug = "";
19
20 public isInstalled() {
21 return "yes";
22 }
23
24 public addDebug(message) {
25 debug += message + "\n";
26 }
27
28 public getDebug() {
29 return debug;
30 }
31
32 public void setContext(context, xwiki) {
33 this.context = context;
34 this.xwiki = xwiki;
35 }
36
37 public String getLoadingUser() {
38 if (defaultUser==null || defaultUser=="")
39 return "XWiki.Admin";
40 else
41 return defaultUser;
42 }
43
44 public void setMailServerFromPage(page) {
45 def settingsDoc = xwiki.getDocument(page);
46 settingsDoc.use("RecruitmentCode.SettingsClass");
47 this.protocol = settingsDoc.getValue("mailprotocol");
48 this.server = settingsDoc.getValue("mailserver");
49 this.user = settingsDoc.getValue("mailuser");
50
51 if (this.server.contains("gmail.com"))
52 this.user = "recent:" + this.user;
53
54 this.pass = settingsDoc.getValue("mailpassword");
55 this.defaultUser = settingsDoc.getValue("user");
56 }
57
58 public void setMailServer(protocol, server, user, pass) {
59 this.protocol = protocol;
60 this.server = server;
61 this.user = user;
62 this.pass = pass;
63 }
64
65 public int checkContacts() {
66 try {
67 return xwiki.mail.checkMail(protocol, server, user, pass)
68 } catch (Throwable e) {
69 addDebug("Failed to connect to mail server " + e.getMessage())
70 return -1;
71 }
72 }
73
74 public boolean loadContact(mail, confirm) {
75 addDebug("Getting mail content");
76 def bodypart = mail.getContent();
77 def content = getMailContent(bodypart);
78 if (content.length()>50000) {
79 content = content.substring(0, 50000);
80 addDebug("Content to big: " + content);
81 }
82
83 def address = getMailAddress(mail, mail.getContent());
84
85 def name = address.personal;
86 def fname = "";
87 def lname = "";
88
89 def pos = name.indexOf(" ");
90 if (pos != -1) {
91 fname = name.substring(0, pos);
92 lname = name.substring(pos + 1);
93 } else {
94 fname = "";
95 lname = name;
96 }
97
98 addDebug("Extracted name: " + name + " - " + fname + " - " + lname);
99
100 def wikiname = xwiki.clearName(name.replaceAll(" ",""));
101
102 addDebug("Wiki name: " + wikiname);
103
104 if (wikiname=="") {
105 addDebug("No name extracted");
106 return false;
107 }
108
109 def contactDoc = xwiki.getDocument("Recruitment.$wikiname")
110 boolean alreadyLoaded = false;
111 if (!contactDoc.isNew()) {
112 contactDoc.use("RecruitmentCode.CandidateClass")
113 def pfname = contactDoc.getValue("first_name")
114 def plname = contactDoc.getValue("last_name")
115 if (pfname==fname && plname==lname) {
116 alreadyLoaded = true;
117 addDebug("contact exist: " + wikiname);
118 } else {
119 if (pfname!=fname)
120 addDebug("fname different");
121 if (plname!=lname)
122 addDebug("lname different");
123 return false;
124 }
125 }
126
127 if (!alreadyLoaded) {
128 def pagename = xwiki.getUniquePageName("Recruitment", wikiname)
129 contactDoc = xwiki.getDocument("Recruitment.${pagename}")
130 contactDoc.use(contactDoc.newObject("RecruitmentCode.CandidateClass"))
131 contactDoc.set("first_name", fname)
132 contactDoc.set("last_name", lname)
133 contactDoc.set("email", address.getAddress())
134 contactDoc.set("status", "none")
135 contactDoc.set("rating", -1)
136 contactDoc.set("details", content)
137 contactDoc.setContent(xwiki.getDocument("RecruitmentCode.CandidateClassTemplate").getContent())
138 contactDoc.setTitle("Candidate ${name}")
139 contactDoc.setComment("Added candidate from email")
140
141 // addDebug("User: " + pagename + "-" + contactDoc.email + "-" + contactDoc.download + "-" + contactDoc.downloaddate + "-" + contactDoc.downloadreason + "-" + contactDoc.first_name + "-" + contactDoc.last_name + "-" + contactDoc.officephone + "-" + contactDoc.country)
142 contactDoc.use(contactDoc.newObject("XWiki.Tags"))
143 contactDoc.set("tags", "candidate")
144 if (confirm) {
145 context.getContext().setUser(getLoadingUser())
146 contactDoc.save()
147
148 def bodyparts = xwiki.getArrayList();
149 def nbAttachs = getMailAttachments(bodypart, bodyparts);
150 addDebug("Attaching " + nbAttachs + " attachments");
151 try {
152 addAttachmentFromMail(contactDoc, bodyparts, context);
153 } catch (Exception e) {
154 e.printStackTrace()
155 addDebug("Failed to attach files to email with exception " + e.getMessage())
156 }
157 return true;
158 }
159 } else {
160 addDebug("Contact already loaded");
161 return false;
162 }
163
164 }
165
166 public boolean loadContacts(int nb, withDelete) {
167 try {
168
169 def loadingUserDoc = xwiki.getDocument(getLoadingUser());
170 if (loadingUserDoc.isNew() || !loadingUserDoc.getObject("XWiki.XWikiUsers")) {
171 addDebug("Loading user set in Settings does not exist. Cannot load emails")
172 return false;
173 }
174
175 // Get a session. Use a blank Properties object.
176 def props = new Properties();
177 // necessary to work with Gmail
178 props.put("mail.imap.partialfetch", "false");
179 props.put("mail.imaps.partialfetch", "false");
180 def session = Session.getInstance(props);
181 // Get a Store object
182 def store = session.getStore(protocol);
183
184 store.connect(server, user, pass)
185 def fldr = store.getFolder("INBOX")
186 fldr.open(Folder.READ_WRITE)
187
188 if (fldr.getMessageCount()< nb)
189 nb = fldr.getMessageCount()
190 def messages = fldr.getMessages(1, nb)
191 for(mail in messages) {
192 try {
193 addDebug("Loading mail")
194 if (loadContact(mail, true)==true) {
195 if (withDelete==true) {
196 mail.setFlag(Flags.Flag.DELETED, true);
197 }
198 }
199 } catch (Exception e) {
200 addDebug("Failed to load mail with exception " + e.getMessage())
201 }
202 }
203 if (withDelete) {
204 fldr.close(true);
205 } else {
206 fldr.close(false);
207 }
208 store.close();
209 System.out.println(getDebug());
210 return true;
211 } catch (Throwable e) {
212 addDebug("Failed to load emails with exception " + e.getMessage())
213 return false;
214 }
215 }
216
217
218 public int addAttachments(doc1, context1) {
219 def doc = doc1.document;
220 def context = context1.context;
221 def xwiki = context.getWiki()
222 int nb = 0;
223 def fileupload = xwiki.getPlugin("fileupload",context)
224 for (fileitem in fileupload.getFileItems(context)) {
225 if (!fileitem.isFormField()) {
226 def name = fileitem.fieldName
227 byte[] data = fileupload.getFileItemData(name, context);
228 if ((data!=null)&&(data.length>0)) {
229 String fname = fileupload.getFileName(name, context);
230 int i = fname.lastIndexOf("\\");
231 if (i==-1)
232 i = fname.lastIndexOf("/");
233 def filename = fname.substring(i+1);
234 filename = filename.replaceAll("\\+"," ");
235 def attachment = new XWikiAttachment();
236 doc.getAttachmentList().add(attachment);
237 attachment.setContent(data);
238 attachment.setFilename(filename);
239 // TODO: handle Author
240 attachment.setAuthor(context1.user);
241 // Add the attachment to the document
242 attachment.setDoc(doc);
243 doc.saveAttachmentContent(attachment, context);
244 nb++;
245 }
246 }
247 }
248 return nb;
249 }
250
251 public int addAttachmentFromMail(doc1, afilename, adata, context1) {
252 def fname = afilename;
253 int i = fname.lastIndexOf("\\");
254 if (i==-1)
255 i = fname.lastIndexOf("/");
256 def filename = fname.substring(i+1);
257 filename = filename.replaceAll("\\+"," ");
258
259 addDebug("adding attachment: " + filename);
260
261 def doc = doc1.getDocument();
262 def context = context1.getContext();
263 def xwiki = context.getWiki()
264 def attachment = new XWikiAttachment();
265 doc.getAttachmentList().add(attachment);
266 attachment.setContent(adata);
267 attachment.setFilename(filename);
268 // TODO: handle Author
269 attachment.setAuthor(context1.user);
270 // Add the attachment to the document
271 attachment.setDoc(doc);
272 addDebug("saving attachment: " + filename);
273 doc.saveAttachmentContent(attachment, context);
274 return 1;
275 }
276
277 public int addAttachmentFromMail(doc1, bodyparts, context1) {
278 def nb = 0;
279 for(bodypart in bodyparts) {
280 String fileName = bodypart.getFileName();
281 addDebug("Treating attachment: " + fileName);
282 if (fileName==null)
283 fileName = "fichier.doc"
284 String disposition = bodypart.getDisposition();
285 String contentType = bodypart.getContentType().toLowerCase();
286
287 addDebug("Treating attachment of type: " + bodypart.getContentType());
288
289 def baos = new ByteArrayOutputStream();
290 OutputStream out = new BufferedOutputStream(baos);
291 // We can't just use p.writeTo() here because it doesn't
292 // decode the attachment. Instead we copy the input stream
293 // onto the output stream which does automatically decode
294 // Base-64, quoted printable, and a variety of other formats.
295 InputStream ins = new BufferedInputStream(bodypart.getInputStream());
296 int b = ins.read()
297 while (b != -1) {
298 out.write(b);
299 b = ins.read();
300 }
301 out.flush();
302 out.close();
303 ins.close();
304
305 addDebug("Treating attachment step 3: " + fileName);
306
307 byte[] data = baos.toByteArray();
308 addDebug("Ready to attach attachment: " + fileName);
309 nb += addAttachmentFromMail(doc1, fileName, data, context1);
310 }
311 return nb;
312 }
313
314 public String getMailContent(bodypart) {
315 String content = ""
316 try {
317 def mcount = bodypart.getCount();
318 def i = 0;
319 while (i<mcount) {
320 def newbodypart = bodypart.getBodyPart(i)
321 if(newbodypart.getContentType().toLowerCase().contains("vcard")) {
322 addDebug("Adding vcard to content");
323 if (!content.toLowerCase().contains("xwiki"))
324 content = "${content} ${newbodypart.content}"
325 } else if(newbodypart.getContentType().toLowerCase().startsWith("text/")) {
326 addDebug("Adding text to content");
327 // addDebug("Adding text to content (type is " + newbodypart.getContentType().toLowerCase() + "): " + newbodypart.content);
328 content = "${content} ${newbodypart.content}"
329 }
330
331
332 if(newbodypart.getContentType().toLowerCase().startsWith("multipart/")) {
333 addDebug("Adding multipart to content");
334 def ncontent = getMailContent(newbodypart.content)
335 if (ncontent!="")
336 content = "${content} ${ncontent}"
337 }
338
339 if (newbodypart.getContentType().toLowerCase().startsWith("message/rfc822")) {
340 addDebug("Adding rfc822 to content");
341 def ncontent = getMailContent(newbodypart.content.content)
342 if (ncontent!="")
343 content = "${content} ${ncontent}"
344 }
345
346 i++;
347 }
348
349 return content;
350 } catch (Exception e) {
351 addDebug("Failed to get Mail Content " + e.getMessage());
352 e.printStackTrace();
353 return "Failed to get Mail Content";
354 }
355 }
356
357
358 public int getMailAttachments(bodypart, bodyparts) {
359 try {
360 def nb = 0;
361 def mcount = bodypart.getCount();
362 def i = 0;
363 while (i<mcount) {
364 def newbodypart = bodypart.getBodyPart(i)
365
366 if(newbodypart.getContentType().toLowerCase().startsWith("application/")) {
367 nb++;
368 bodyparts.add(newbodypart)
369 }
370
371 if(newbodypart.getContentType().toLowerCase().startsWith("multipart/")) {
372 nb += getMailAttachments(newbodypart.content,bodyparts)
373 }
374
375 if(newbodypart.getContentType().toLowerCase().startsWith("message/rfc822")) {
376 nb += getMailAttachments(newbodypart.content.content,bodyparts)
377 }
378
379 i++;
380 }
381 return nb;
382 } catch (Exception e) {
383 return 0;
384 }
385 }
386
387 public Object getMailAddress(message, bodypart) {
388 def address = (message==null) ? "" : message.getFrom()[0];
389 addDebug("Found address: " + address);
390 try {
391 def mcount = bodypart.getCount();
392 addDebug("Found body parts: " + mcount);
393 def i = 0;
394 while (i<mcount) {
395 def newbodypart = bodypart.getBodyPart(i)
396
397 addDebug("Checking body part " + i + " " + newbodypart.getContentType().toLowerCase());
398
399 if(newbodypart.getContentType().toLowerCase().startsWith("multipart/")) {
400 def add = getMailAddress(null, newbodypart.content)
401 addDebug("Found address in multipart: " + add);
402 if ((add!=null)&&(add!=""))
403 address = add;
404 }
405
406 if (newbodypart.getContentType().toLowerCase().startsWith("message/rfc822")) {
407 def add = getMailAddress(newbodypart.content, newbodypart.content.content)
408 addDebug("Found address in rfc822: " + add);
409 if ((add!=null)&&(add!=""))
410 address = add;
411 }
412
413 i++;
414 }
415 return address;
416 } catch (Exception e) {
417 return address;
418 }
419 }
420
421 public Map readMail(content) {
422 def map = new HashMap();
423 def lines = content.split("\n")
424 for (line in lines) {
425 def i = line.indexOf("=");
426 if (i!=-1) {
427 def key = line.substring(0, i).trim();
428 def value = line.substring(i+1).trim();
429 if (mapping.get(key))
430 key = mapping.get(key);
431 map.put(key, value);
432 }
433 }
434 return map;
435 }
436
437
438 }