korganizer

komailclient.cpp
1 /*
2  This file is part of KOrganizer.
3  Copyright (c) 1998 Barry D Benowitz
4  Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20  As a special exception, permission is given to link this program
21  with any edition of TQt, and distribute the resulting executable,
22  without including the source code for TQt in the source distribution.
23 */
24 
25 #include <unistd.h>
26 #include <stdio.h>
27 
28 #include <tdelocale.h>
29 #include <kstandarddirs.h>
30 #include <kdebug.h>
31 #include <tdemessagebox.h>
32 #include <kurl.h>
33 #include <tdeapplication.h>
34 #include <dcopclient.h>
35 #include <kprocess.h>
36 
37 #include <libemailfunctions/email.h>
38 
39 #include <libkpimidentities/identity.h>
40 #include <libkpimidentities/identitymanager.h>
41 
42 #include <libkcal/event.h>
43 #include <libkcal/todo.h>
44 #include <libkcal/incidenceformatter.h>
45 
46 #include "version.h"
47 #include "koprefs.h"
48 #include "kocore.h"
49 
50 #include "komailclient.h"
51 
52 KOMailClient::KOMailClient()
53 {
54 }
55 
56 KOMailClient::~KOMailClient()
57 {
58 }
59 
60 bool KOMailClient::mailAttendees(IncidenceBase *incidence,const TQString &attachment)
61 {
62  Attendee::List attendees = incidence->attendees();
63  if ( attendees.count() == 0 ) {
64  return false;
65  }
66 
67  const TQString from = incidence->organizer().fullName();
68  const TQString organizerEmail = incidence->organizer().email();
69 
70  TQStringList toList;
71  TQStringList ccList;
72  for ( uint i=0; i<attendees.count(); ++i ) {
73  Attendee *a = (*attendees.at(i));
74 
75  const TQString email = a->email();
76  if ( email.isEmpty() ) {
77  continue;
78  }
79 
80  // In case we (as one of our identities) are the organizer we are sending
81  // this mail. We could also have added ourselves as an attendee, in which
82  // case we don't want to send ourselves a notification mail.
83  if ( organizerEmail == email ) {
84  continue;
85  }
86 
87  // Build a nice address for this attendee including the CN.
88  TQString tname, temail;
89  const TQString username = KPIM::quoteNameIfNecessary( a->name() );
90  KPIM::getNameAndMail( username, tname, temail ); // ignore return value
91  // which is always false
92  tname += " <" + email + '>';
93 
94 
95  // Optional Participants and Non-Participants are copied on the email
96  if ( a->role() == Attendee::OptParticipant ||
97  a->role() == Attendee::NonParticipant ) {
98  ccList << tname;
99  } else {
100  toList << tname;
101  }
102  }
103 
104  if( toList.count() == 0 && ccList.count() == 0 ) {
105  // Not really to be called a groupware meeting, eh
106  return false;
107  }
108  TQString to;
109  if ( toList.count() > 0 ) {
110  to = toList.join( ", " );
111  }
112  TQString cc;
113  if ( ccList.count() > 0 ) {
114  cc = ccList.join( ", " );
115  }
116 
117  TQString subject;
118  if(incidence->type()!="FreeBusy") {
119  Incidence *inc = static_cast<Incidence *>(incidence);
120  subject = inc->summary();
121  } else {
122  subject = "Free Busy Object";
123  }
124 
125  TQString body = IncidenceFormatter::mailBodyString(incidence);
126 
127  bool bcc = KOPrefs::instance()->mBcc;
128 
129  return send(from,to,cc,subject,body,bcc,attachment);
130 }
131 
132 bool KOMailClient::mailOrganizer(IncidenceBase *incidence,const TQString &attachment, const TQString &sub)
133 {
134  TQString to = incidence->organizer().fullName();
135 
136  TQString from = KOPrefs::instance()->email();
137 
138  TQString subject = sub;
139  if(incidence->type()!="FreeBusy") {
140  Incidence *inc = static_cast<Incidence *>(incidence);
141  if ( subject.isEmpty() )
142  subject = inc->summary();
143  } else {
144  subject = "Free Busy Message";
145  }
146 
147  TQString body = IncidenceFormatter::mailBodyString(incidence);
148 
149  bool bcc = KOPrefs::instance()->mBcc;
150 
151  return send(from,to,TQString(),subject,body,bcc,attachment);
152 }
153 
154 bool KOMailClient::mailTo(IncidenceBase *incidence,const TQString &recipients,
155  const TQString &attachment)
156 {
157  TQString from = KOPrefs::instance()->email();
158  TQString subject;
159  if(incidence->type()!="FreeBusy") {
160  Incidence *inc = static_cast<Incidence *>(incidence);
161  subject = inc->summary();
162  } else {
163  subject = "Free Busy Message";
164  }
165  TQString body = IncidenceFormatter::mailBodyString(incidence);
166  bool bcc = KOPrefs::instance()->mBcc;
167  kdDebug () << "KOMailClient::mailTo " << recipients << endl;
168  return send(from,recipients,TQString(),subject,body,bcc,attachment);
169 }
170 
171 bool KOMailClient::send(const TQString &from,const TQString &_to,const TQString &cc,
172  const TQString &subject,const TQString &body,bool bcc,
173  const TQString &attachment)
174 {
175  // We must have a recipients list for most MUAs. Thus, if the 'to' list
176  // is empty simply use the 'from' address as the recipient.
177  TQString to = _to;
178  if ( to.isEmpty() ) {
179  to = from;
180  }
181 
182  kdDebug(5850) << "KOMailClient::sendMail():\nFrom: " << from
183  << "\nTo: " << to
184  << "\nCC: " << cc
185  << "\nSubject: " << subject << "\nBody: \n" << body
186  << "\nAttachment:\n" << attachment << endl;
187 
188  if (KOPrefs::instance()->mMailClient == KOPrefs::MailClientSendmail) {
189  bool needHeaders = true;
190 
191  TQString command = TDEStandardDirs::findExe(TQString::fromLatin1("sendmail"),
192  TQString::fromLatin1("/sbin:/usr/sbin:/usr/lib"));
193  if (!command.isNull()) command += TQString::fromLatin1(" -oi -t");
194  else {
195  command = TDEStandardDirs::findExe(TQString::fromLatin1("mail"));
196  if (command.isNull()) return false; // give up
197 
198  command.append(TQString::fromLatin1(" -s "));
199  command.append(TDEProcess::quote(subject));
200 
201  if (bcc) {
202  command.append(TQString::fromLatin1(" -b "));
203  command.append(TDEProcess::quote(from));
204  }
205 
206  if ( !cc.isEmpty() ) {
207  command.append(" -c ");
208  command.append(TDEProcess::quote(cc));
209  }
210 
211  command.append(" ");
212  command.append(TDEProcess::quote(to));
213 
214  needHeaders = false;
215  }
216 
217  FILE * fd = popen(command.local8Bit(),"w");
218  if (!fd)
219  {
220  kdError() << "Unable to open a pipe to " << command << endl;
221  return false;
222  }
223 
224  TQString textComplete;
225  if (needHeaders)
226  {
227  textComplete += TQString::fromLatin1("From: ") + from + '\n';
228  textComplete += TQString::fromLatin1("To: ") + to + '\n';
229  if ( !cc.isEmpty() ) {
230  textComplete += TQString::fromLatin1("Cc: " ) + cc + '\n';
231  }
232  if (bcc) textComplete += TQString::fromLatin1("Bcc: ") + from + '\n';
233  textComplete += TQString::fromLatin1("Subject: ") + subject + '\n';
234  textComplete += TQString::fromLatin1("X-Mailer: KOrganizer") + korgVersion + '\n';
235  }
236  textComplete += '\n'; // end of headers
237  textComplete += body;
238  textComplete += '\n';
239  textComplete += attachment;
240 
241  fwrite(textComplete.local8Bit(),textComplete.length(),1,fd);
242 
243  pclose(fd);
244  } else {
245  if (!kapp->dcopClient()->isApplicationRegistered("kmail")) {
246  if (TDEApplication::startServiceByDesktopName("kmail")) {
247  KMessageBox::error(0,i18n("No running instance of KMail found."));
248  return false;
249  }
250  }
251 
252  if (attachment.isEmpty()) {
253  if (!kMailOpenComposer(to,cc,bcc ? from : "",subject,body,0,KURL())) return false;
254  } else {
255  TQString meth;
256  int idx = attachment.find("METHOD");
257  if (idx>=0) {
258  idx = attachment.find(':',idx)+1;
259  const int newline = attachment.find('\n',idx);
260  meth = attachment.mid(idx, newline - idx - 1);
261  meth = meth.lower().stripWhiteSpace();
262  } else {
263  meth = "publish";
264  }
265  if (!kMailOpenComposer(to,cc,bcc ? from : "",subject,body,0,"cal.ics","7bit",
266  attachment.utf8(),"text","calendar","method",meth,
267  "attachment","utf-8",
268  KOCore::self()->identityManager()->identityForAddress( from ).uoid())) {
269  return false;
270  }
271  }
272  }
273  return true;
274 }
275 
276 int KOMailClient::kMailOpenComposer(const TQString& arg0,const TQString& arg1,
277  const TQString& arg2,const TQString& arg3,const TQString& arg4,int arg5,
278  const KURL& arg6)
279 {
280  //kdDebug(5850) << "KOMailClient::kMailOpenComposer( "
281  // << arg0 << " , " << arg1 << arg2 << " , " << arg3
282  // << arg4 << " , " << arg5 << " , " << arg6 << " )" << endl;
283  int result = 0;
284 
285  TQByteArray data, replyData;
286  TQCString replyType;
287  TQDataStream arg( data, IO_WriteOnly );
288  arg << arg0;
289  arg << arg1;
290  arg << arg2;
291  arg << arg3;
292  arg << arg4;
293  arg << arg5;
294  arg << arg6;
295 #if KDE_IS_VERSION( 3, 2, 90 )
296  kapp->updateRemoteUserTimestamp( "kmail" );
297 #endif
298  if (kapp->dcopClient()->call("kmail","KMailIface","openComposer(TQString,TQString,TQString,TQString,TQString,int,KURL)", data, replyType, replyData ) ) {
299  if ( replyType == "int" ) {
300  TQDataStream _reply_stream( replyData, IO_ReadOnly );
301  _reply_stream >> result;
302  } else {
303  kdDebug(5850) << "kMailOpenComposer() call failed." << endl;
304  }
305  } else {
306  kdDebug(5850) << "kMailOpenComposer() call failed." << endl;
307  }
308  return result;
309 }
310 
311 int KOMailClient::kMailOpenComposer( const TQString& arg0, const TQString& arg1,
312  const TQString& arg2, const TQString& arg3,
313  const TQString& arg4, int arg5, const TQString& arg6,
314  const TQCString& arg7, const TQCString& arg8,
315  const TQCString& arg9, const TQCString& arg10,
316  const TQCString& arg11, const TQString& arg12,
317  const TQCString& arg13, const TQCString& arg14, uint identity )
318 {
319  //kdDebug(5850) << "KOMailClient::kMailOpenComposer( "
320  // << arg0 << " , " << arg1 << arg2 << " , " << arg3
321  // << arg4 << " , " << arg5 << " , " << arg6
322  // << arg7 << " , " << arg8 << " , " << arg9
323  // << arg10<< " , " << arg11<< " , " << arg12
324  // << arg13<< " , " << arg14<< " )" << endl;
325 
326  int result = 0;
327 
328  TQByteArray data, replyData;
329  TQCString replyType;
330  TQDataStream arg( data, IO_WriteOnly );
331  arg << arg0;
332  arg << arg1;
333  arg << arg2;
334  arg << arg3;
335  arg << arg4;
336  arg << arg5;
337  arg << arg6;
338  arg << arg7;
339  arg << arg8;
340  arg << arg9;
341  arg << arg10;
342  arg << arg11;
343  arg << arg12;
344  arg << arg13;
345  arg << arg14;
346  arg << identity;
347 #if KDE_IS_VERSION( 3, 2, 90 )
348  kapp->updateRemoteUserTimestamp("kmail");
349 #endif
350  if ( kapp->dcopClient()->call("kmail","KMailIface",
351  "openComposer(TQString,TQString,TQString,TQString,TQString,int,TQString,TQCString,TQCString,TQCString,TQCString,TQCString,TQString,TQCString,TQCString,uint)", data, replyType, replyData ) ) {
352  if ( replyType == "int" ) {
353  TQDataStream _reply_stream( replyData, IO_ReadOnly );
354  _reply_stream >> result;
355  } else {
356  kdDebug(5850) << "kMailOpenComposer() call failed." << endl;
357  }
358  } else {
359  kdDebug(5850) << "kMailOpenComposer() call failed." << endl;
360  }
361  return result;
362 }
363 
364 
Role role() const
const Attendee::List & attendees() const
TQString summary() const