BrightSide Workbench Full Report + Source Code
ConvocationSender.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2018 Lluis TurrĂ³ Cutiller <http://www.turro.org/>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Affero General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Affero General Public License for more details.
14  *
15  * You should have received a copy of the GNU Affero General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 package org.turro.zul.convocation;
20 
21 import biweekly.ICalVersion;
22 import biweekly.ICalendar;
23 import biweekly.component.VEvent;
24 import biweekly.io.text.ICalWriter;
25 import biweekly.parameter.ParticipationStatus;
26 import biweekly.parameter.Role;
27 import biweekly.property.Classification;
28 import biweekly.property.Organizer;
29 import biweekly.property.Status;
30 import java.io.File;
31 import java.io.IOException;
32 import java.util.ArrayList;
33 import java.util.List;
34 import java.util.logging.Level;
35 import java.util.logging.Logger;
36 import java.util.regex.Matcher;
37 import java.util.regex.Pattern;
38 import org.turro.string.Strings;
39 import org.apache.commons.mail.EmailException;
40 import org.turro.action.Contacts;
41 import org.turro.action.IAgreements;
42 import org.turro.action.Plugins;
43 import org.turro.action.queue.NotificationCategory;
44 import org.turro.action.queue.Notifications;
45 import org.turro.assistant.Assistant;
46 import org.turro.assistant.AssistantSet;
47 import org.turro.contacts.Attendee;
48 import org.turro.contacts.Connector;
49 import org.turro.contacts.Contact;
50 import org.turro.contacts.Convocation;
51 import org.turro.elephant.context.Application;
52 import org.turro.elephant.context.ElephantContext;
53 import org.turro.elephant.security.IUser;
54 import org.turro.log.SystemLogType;
55 import org.turro.log.SystemLogger;
56 import org.turro.mail.message.MailMessageTemplate;
57 import org.turro.mail.message.MailUtils;
58 import org.turro.mail.pool.MailMessagePool;
59 import org.turro.mail.provider.MailProviders;
60 import org.turro.mail.queue.GenericElephantNotification;
61 import org.turro.mail.queue.QueuedSender;
62 import org.turro.marker.ElephantMarker;
63 import org.turro.plugin.contacts.IContact;
64 import org.turro.www.convocation.ConvocationCtrl;
65 
70 public class ConvocationSender extends QueuedSender {
71 
72  private final Convocation entity;
73  private final AssistantSet assistants;
74  private final IContact contact;
75 
76  public ConvocationSender(Convocation entity, IContact contact) {
77  this.entity = entity;
78  this.assistants = null;
79  this.contact = contact;
80  }
81 
82  public ConvocationSender(Convocation entity, AssistantSet assistants) {
83  this.entity = entity;
84  this.assistants = assistants;
85  this.contact = null;
86  }
87 
88  @Override
89  protected void doSend() {
90  final List<File> tmpFiles = new ArrayList<>();
92  if(pool != null) {
93  String organizerEmail = null;
94  if(entity.getOrganizer() != null) {
96  if(c != null) {
97  organizerEmail = c.getValue();
98  }
99  }
100  if(contact != null) {
101  createMail(new Assistant(contact, entity), tmpFiles, organizerEmail, pool);
102  } else {
103  IAgreements agreements = Plugins.loadImplementation(IAgreements.class, "agreements");
105  for(Assistant assistant : assistants) {
106  agreements.setContact(assistant.contact);
107  if(agreements.canSendEmails(nc)) {
108  createMail(assistant, tmpFiles, organizerEmail, pool);
109  }
110  }
111  }
112  pool.sendPool((m) -> {
113  for(File f : tmpFiles) {
114  f.delete();
115  }
116  });
117  SystemLogger.getInstance().doLog(SystemLogType.LOG_INFO, entity, "sent", organizerEmail);
118  }
119  }
120 
121  private void createMail(Assistant assistant, final List<File> tmpFiles, String organizerEmail, MailMessagePool pool) {
122  try {
123  if(Contacts.isValidEmail(assistant.email)) {
124  File tmp = generateCalendar(assistant.contact, assistant.email);
125  tmpFiles.add(tmp);
127  mmt.setSubject(entity.getName());
128  if(checkWebDomain(organizerEmail)) {
129  mmt.setFrom(organizerEmail, entity.getOrganizer().getName());
130  }
131  mmt.addTo(assistant.email, assistant.name);
132  ElephantMarker em = new ElephantMarker(Application.getApplication().getConstructor(), true);
133  em.put("convocation", entity);
134  em.put("contact", assistant.contact);
135  em.put("email", assistant.email);
136  em.put("notifier", this);
137  mmt.setMessage(em, "convocation", assistant.contact);
138  mmt.attach(tmp.getAbsolutePath(), "invite.ics", "invite.ics");
139  pool.addToPool(mmt);
140  }
141  } catch (EmailException ex) {
142  Logger.getLogger(ConvocationSender.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
143  }
144  }
145 
146  private File generateCalendar(IContact contact, String email) {
147  try {
148  ICalendar cal = new ICalendar();
149  cal.setVersion(ICalVersion.V2_0);
150  cal.setProductId(ElephantContext.getSiteName());
151  cal.setMethod(biweekly.property.Method.request());
152  VEvent event = new VEvent();
153  event.setUid(entity.getId());
154  event.setStatus(Status.confirmed());
155  event.setClassification(Classification.public_());
156  event.setSummary(entity.getName());
157  event.setDateStart(entity.getCallDate());
158  event.setDateEnd(entity.getEndDate());
159  event.setDescription(MailUtils.processMacros(contact, entity.getPlainText()));
160  if(!Strings.isBlank(entity.getLocation())) {
161  event.setLocation(entity.getLocation());
162  }
163  Contact organizer = entity.getOrganizer();
164  if(organizer != null) {
165  Organizer o = new Organizer(organizer.getName(), organizer.getConnectorMap().get(IUser.CONNECTOR_EMAIL).getValue());
166  event.setOrganizer(o);
167  }
168  if(contact != null && !Strings.isBlank(email)) {
169  biweekly.property.Attendee at = new biweekly.property.Attendee(contact.getName(), email);
170  at.setRole(Role.ATTENDEE);
171  at.setParticipationStatus(ParticipationStatus.NEEDS_ACTION);
172  at.setRsvp(Boolean.TRUE);
173  event.addAttendee(at);
174  }
175  cal.addEvent(event);
176  File tmp = File.createTempFile("attach_", "_calendar.ics");
177  try (ICalWriter writer = new ICalWriter(tmp, ICalVersion.V2_0)) {
178  writer.write(cal);
179  }
180  //Biweekly.write(cal).go(tmp);
181  return tmp;
182  } catch (IOException ex) {
183  Logger.getLogger(ConvocationSender.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
184  }
185  return null;
186  }
187 
188  private boolean checkWebDomain(String organizerEmail) {
189  Pattern p = Pattern.compile(".*[^a-zA-Z0-9-]([a-zA-Z0-9-]+\\.[a-zA-Z0-9-]+)[^a-zA-Z0-9-]*");
190  String domainServer = null, domainMail = null;
191  String server = ElephantContext.getServerBase("http");
192  Matcher m = p.matcher(server);
193  if(m.find()) {
194  domainServer = m.group(1);
195  }
196  m = p.matcher(organizerEmail);
197  if(m.find()) {
198  domainMail = m.group(1);
199  }
200  return !Strings.isBlank(domainServer) &&
201  !Strings.isBlank(domainMail) &&
202  domainServer.equals(domainMail);
203  }
204 
205  public String createAttendantQrCode(IContact contact, Convocation convocation) {
207  }
208 
209  public static AssistantSet getAsAssistants(Convocation convocation) {
210  AssistantSet assistants = new AssistantSet();
211  for(Attendee att : convocation.getAttendees()) {
212  assistants.addContact(att.getIContact(), convocation);
213  }
214  return assistants;
215  }
216 
217 }
static boolean isValidEmail(String email)
Definition: Contacts.java:99
static< T > T loadImplementation(Class< T > jclass)
Definition: Plugins.java:57
static NotificationCategory getCategory(String id)
void addContact(IContact contact, Object relationEntity)
Map< String, Connector > getConnectorMap()
Definition: Contact.java:499
Set< Attendee > getAttendees()
static ISystemLogger getInstance()
MailMessage addToPool(String from, String to, String cc, String subject, String message)
static String createAttendantQrCodeURL(IConstructor constructor, IContact contact, Convocation convocation)
ConvocationSender(Convocation entity, IContact contact)
ConvocationSender(Convocation entity, AssistantSet assistants)
String createAttendantQrCode(IContact contact, Convocation convocation)
static AssistantSet getAsAssistants(Convocation convocation)
boolean canSendEmails(NotificationCategory nc)
void setContact(IContact contact)
static final String CONNECTOR_EMAIL
Definition: IUser.java:27
void doLog(SystemLogType type, Object entity, String comment, Serializable data)