void BenchmarkTests::parsingBenchmarkComparison() { const KMime::Message::Ptr kolabItem = readMimeFile( TESTFILEDIR+QString::fromLatin1("/v2/event/complex.ics.mime") ); KMime::Content *xmlContent = findContentByType( kolabItem, "application/x-vnd.kolab.event" ); QVERIFY ( xmlContent ); const QByteArray xmlData = xmlContent->decodedContent(); // qDebug() << xmlData; const QDomDocument xmlDoc = KolabV2::Event::loadDocument( QString::fromUtf8(xmlData) ); QVERIFY ( !xmlDoc.isNull() ); const KCalCore::Event::Ptr i = KolabV2::Event::fromXml( xmlDoc, QString::fromLatin1("Europe/Berlin") ); QVERIFY ( i ); const Kolab::Event &event = Kolab::Conversion::fromKCalCore(*i); const std::string &v3String = Kolab::writeEvent(event); QFETCH(bool, v2Parser); // Kolab::readEvent(v3String, false); //init parser (doesn't really change the results it seems) // qDebug() << QString::fromUtf8(xmlData); // qDebug() << "------------------------------------------------------------------------------------"; // qDebug() << QString::fromStdString(v3String); if (v2Parser) { QBENCHMARK { KolabV2::Event::fromXml( KolabV2::Event::loadDocument( QString::fromUtf8(xmlData) ), QString::fromLatin1("Europe/Berlin") ); } } else {
int MimeTreeModel::rowCount(const QModelIndex & parent) const { if ( !d->root ) return 0; if ( !parent.isValid() ) return 1; KMime::Content *parentContent = static_cast<KMime::Content*>( parent.internalPointer() ); if ( parentContent ) return parentContent->contents().count(); return 0; }
KMime::Content *createPlainPartContent(const KMime::Message::Ptr &msg, const QString &plainBody) { KMime::Content *textPart = new KMime::Content(msg.data()); textPart->contentType()->setMimeType("text/plain"); //FIXME This is supposed to select a charset out of the available charsets that contains all necessary characters to render the text // QTextCodec *charset = selectCharset(m_charsets, plainBody); // textPart->contentType()->setCharset(charset->name()); textPart->contentType()->setCharset("utf-8"); textPart->contentTransferEncoding()->setEncoding(KMime::Headers::CE8Bit); textPart->fromUnicodeString(plainBody); return textPart; }
QModelIndex MimeTreeModel::index(int row, int column, const QModelIndex &parent) const { if ( !parent.isValid() ) { if ( row != 0 ) return QModelIndex(); return createIndex( row, column, d->root ); } KMime::Content *parentContent = static_cast<KMime::Content*>( parent.internalPointer() ); if ( !parentContent || parentContent->contents().count() <= row || row < 0 ) return QModelIndex(); KMime::Content *content = parentContent->contents().at( row ); return createIndex( row, column, content ); }
MimeMessagePart::Ptr MimeTreeParser::createAndParseTempNode(Interface::BodyPart &part, KMime::Content *parentNode, const char *content, const char *cntDesc) { KMime::Content *newNode = new KMime::Content(); newNode->setContent(KMime::CRLFtoLF(content)); newNode->parse(); if (!newNode->head().isEmpty()) { newNode->contentDescription()->from7BitString(cntDesc); } auto mp = MimeMessagePart::Ptr(new MimeMessagePart(part.objectTreeParser(), newNode, false)); mp->bindLifetime(newNode); return mp; }
Interface::MessagePart::Ptr MultiPartAlternativeBodyPartFormatter::process(Interface::BodyPart &part) const { KMime::Content *node = part.content(); if (node->contents().isEmpty()) { return MessagePart::Ptr(); } KMime::Content *dataHtml = findTypeInDirectChilds(node, "text/html"); KMime::Content *dataPlain = findTypeInDirectChilds(node, "text/plain"); if (!dataHtml) { // If we didn't find the HTML part as the first child of the multipart/alternative, it might // be that this is a HTML message with images, and text/plain and multipart/related are the // immediate children of this multipart/alternative node. // In this case, the HTML node is a child of multipart/related. dataHtml = findTypeInDirectChilds(node, "multipart/related"); // Still not found? Stupid apple mail actually puts the attachments inside of the // multipart/alternative, which is wrong. Therefore we also have to look for multipart/mixed // here. // Do this only when prefering HTML mail, though, since otherwise the attachments are hidden // when displaying plain text. if (!dataHtml && part.source()->htmlMail()) { dataHtml = findTypeInDirectChilds(node, "multipart/mixed"); } } if (dataPlain || dataHtml) { AlternativeMessagePart::Ptr mp(new AlternativeMessagePart(part.objectTreeParser(), dataPlain, dataHtml)); if ((part.source()->htmlMail() && dataHtml) || (dataHtml && dataPlain && dataPlain->body().isEmpty())) { if (dataPlain) { part.nodeHelper()->setNodeProcessed(dataPlain, false); } part.source()->setHtmlMode(Util::MultipartHtml); mp->setViewHtml(true); } if (!part.source()->htmlMail() && dataPlain) { part.nodeHelper()->setNodeProcessed(dataHtml, false); part.source()->setHtmlMode(Util::MultipartPlain); mp->setViewHtml(false); } return mp; } MimeMessagePart::Ptr mp(new MimeMessagePart(part.objectTreeParser(), node->contents().at(0), false)); return mp; }
MessagePart::Ptr ApplicationPGPEncryptedBodyPartFormatter::process(Interface::BodyPart &part) const { KMime::Content *node(part.content()); if (node->decodedContent().trimmed() != "Version: 1") { qCWarning(MIMETREEPARSER_LOG) << "Unknown PGP Version String:" << node->decodedContent().trimmed(); } if (!part.content()->parent()) { return MessagePart::Ptr(); } KMime::Content *data = findTypeInDirectChilds(part.content()->parent(), "application/octet-stream"); if (!data) { return MessagePart::Ptr(); //new MimeMessagePart(part.objectTreeParser(), node, false)); } EncryptedMessagePart::Ptr mp(new EncryptedMessagePart(part.objectTreeParser(), data->decodedText(), QGpgME::openpgp(), part.nodeHelper()->fromAsString(data), node, data)); mp->setIsEncrypted(true); return mp; }
void MailClient::send( const KPIMIdentities::Identity &identity, const QString &from, const QString &_to, const QString &cc, const QString &subject, const QString &body, bool hidden, bool bccMe, const QString &attachment, const QString &mailTransport ) { Q_UNUSED( identity ); Q_UNUSED( hidden ); #ifdef MAILCLIENTTEST_UNITTEST mUnitTestResult.message = KMime::Message::Ptr(); mUnitTestResult.from.clear(); mUnitTestResult.to.clear(); mUnitTestResult.cc.clear(); mUnitTestResult.bcc.clear(); mUnitTestResult.transportId = -1; #endif if ( !MailTransport::TransportManager::self()->showTransportCreationDialog( 0, MailTransport::TransportManager::IfNoTransportExists ) ) { kError() << "Error while creating transport"; emit finished( ResultErrorCreatingTransport, i18n( "Error while creating transport" ) ); return; } // We must have a recipients list for most MUAs. Thus, if the 'to' list // is empty simply use the 'from' address as the recipient. QString to = _to; if ( to.isEmpty() ) { to = from; } kDebug() << "\nFrom:" << from << "\nTo:" << to << "\nCC:" << cc << "\nSubject:" << subject << "\nBody: \n" << body << "\nAttachment:\n" << attachment << "\nmailTransport: " << mailTransport; QTime timer; timer.start(); MailTransport::Transport *transport = MailTransport::TransportManager::self()->transportByName( mailTransport ); if ( !transport ) { transport = MailTransport::TransportManager::self()->transportByName( MailTransport::TransportManager::self()->defaultTransportName() ); } if ( !transport ) { kError() << "Error fetching transport; mailTransport" << mailTransport << MailTransport::TransportManager::self()->defaultTransportName(); emit finished( ResultErrorFetchingTransport, i18n( "Error fetching transport. Unable to send invitations" ) ); return; } const int transportId = transport->id(); // gather config values KConfig config( QLatin1String( "mailviewerrc" ) ); KConfigGroup configGroup( &config, QLatin1String( "Invitations" ) ); const bool outlookConformInvitation = configGroup.readEntry( "LegacyBodyInvites", #ifdef KDEPIM_ENTERPRISE_BUILD true #else false #endif ); // Now build the message we like to send. The message KMime::Message::Ptr instance // will be the root message that has 2 additional message. The body itself and // the attached cal.ics calendar file. KMime::Message::Ptr message = KMime::Message::Ptr( new KMime::Message ); message->contentTransferEncoding()->clear(); // 7Bit, decoded. // Set the headers message->userAgent()->fromUnicodeString( KProtocolManager::userAgentForApplication( QLatin1String( "KOrganizer" ), QLatin1String( KDEPIMLIBS_VERSION ) ), "utf-8" ); message->from()->fromUnicodeString( from, "utf-8" ); message->to()->fromUnicodeString( to, "utf-8" ); message->cc()->fromUnicodeString( cc, "utf-8" ); if( bccMe ) { message->bcc()->fromUnicodeString( from, "utf-8" ); //from==me, right? } message->date()->setDateTime( KDateTime::currentLocalDateTime() ); message->subject()->fromUnicodeString( subject, "utf-8" ); if ( outlookConformInvitation ) { message->contentType()->setMimeType( "text/calendar" ); message->contentType()->setCharset( "utf-8" ); message->contentType()->setName( QLatin1String( "cal.ics" ), "utf-8" ); message->contentType()->setParameter( QLatin1String( "method" ), QLatin1String( "request" ) ); if ( !attachment.isEmpty() ) { KMime::Headers::ContentDisposition *disposition = new KMime::Headers::ContentDisposition( message.get() ); disposition->setDisposition( KMime::Headers::CDinline ); message->setHeader( disposition ); message->contentTransferEncoding()->setEncoding( KMime::Headers::CEquPr ); message->setBody( KMime::CRLFtoLF( attachment.toUtf8() ) ); } } else { // We need to set following 4 lines by hand else KMime::Content::addContent // will create a new Content instance for us to attach the main message // what we don't need cause we already have the main message instance where // 2 additional messages are attached. KMime::Headers::ContentType *ct = message->contentType(); ct->setMimeType( "multipart/mixed" ); ct->setBoundary( KMime::multiPartBoundary() ); ct->setCategory( KMime::Headers::CCcontainer ); // Set the first multipart, the body message. KMime::Content *bodyMessage = new KMime::Content; KMime::Headers::ContentDisposition *bodyDisposition = new KMime::Headers::ContentDisposition( bodyMessage ); bodyDisposition->setDisposition( KMime::Headers::CDinline ); bodyMessage->contentType()->setMimeType( "text/plain" ); bodyMessage->contentType()->setCharset( "utf-8" ); bodyMessage->contentTransferEncoding()->setEncoding( KMime::Headers::CEquPr ); bodyMessage->setBody( KMime::CRLFtoLF( body.toUtf8() ) ); message->addContent( bodyMessage ); // Set the sedcond multipart, the attachment. if ( !attachment.isEmpty() ) { KMime::Content *attachMessage = new KMime::Content; KMime::Headers::ContentDisposition *attachDisposition = new KMime::Headers::ContentDisposition( attachMessage ); attachDisposition->setDisposition( KMime::Headers::CDattachment ); attachMessage->contentType()->setMimeType( "text/calendar" ); attachMessage->contentType()->setCharset( "utf-8" ); attachMessage->contentType()->setName( QLatin1String( "cal.ics" ), "utf-8" ); attachMessage->contentType()->setParameter( QLatin1String( "method" ), QLatin1String( "request" ) ); attachMessage->setHeader( attachDisposition ); attachMessage->contentTransferEncoding()->setEncoding( KMime::Headers::CEquPr ); attachMessage->setBody( KMime::CRLFtoLF( attachment.toUtf8() ) ); message->addContent( attachMessage ); } } // Job done, attach the both multiparts and assemble the message. message->assemble(); // Put the newly created item in the MessageQueueJob. MailTransport::MessageQueueJob *qjob = new MailTransport::MessageQueueJob( this ); qjob->transportAttribute().setTransportId( transportId ); qjob->sentBehaviourAttribute().setSentBehaviour( MailTransport::SentBehaviourAttribute::MoveToDefaultSentCollection ); const QString unormalizedFrom = ( transport && transport->specifySenderOverwriteAddress() ) ? transport->senderOverwriteAddress() : from; const QString normalizedFrom = KPIMUtils::extractEmailAddress( KPIMUtils::normalizeAddressesAndEncodeIdn( unormalizedFrom ) ); const QString finalFrom = KPIMUtils::extractEmailAddress( normalizedFrom ); qjob->addressAttribute().setFrom( finalFrom ); QStringList toStringList; if( !to.isEmpty() ) { toStringList = extractEmailAndNormalize( to ); qjob->addressAttribute().setTo( toStringList ); } QStringList ccStringList; if( !cc.isEmpty() ) { ccStringList = extractEmailAndNormalize( cc ); qjob->addressAttribute().setCc( ccStringList ); } QStringList bccStringList; if ( bccMe ) { bccStringList = extractEmailAndNormalize( from ); qjob->addressAttribute().setBcc( bccStringList ); } qjob->setMessage( message ); connect( qjob, SIGNAL(finished(KJob*)), SLOT(handleQueueJobFinished(KJob*)) ); qjob->start(); #ifdef MAILCLIENTTEST_UNITTEST mUnitTestResult.message = message; mUnitTestResult.from = finalFrom; mUnitTestResult.to = toStringList; mUnitTestResult.cc = ccStringList; mUnitTestResult.bcc = bccStringList; mUnitTestResult.transportId = transportId; #endif }
KMime::Content *createMultipartAlternativeContent(const KMime::Message::Ptr &msg, const QString &plainBody, const QString &htmlBody) { KMime::Content *multipartAlternative = new KMime::Content(msg.data()); multipartAlternative->contentType()->setMimeType("multipart/alternative"); const QByteArray boundary = KMime::multiPartBoundary(); multipartAlternative->contentType()->setBoundary(boundary); KMime::Content *textPart = createPlainPartContent(msg, plainBody); multipartAlternative->addContent(textPart); KMime::Content *htmlPart = new KMime::Content(msg.data()); htmlPart->contentType()->setMimeType("text/html"); //FIXME This is supposed to select a charset out of the available charsets that contains all necessary characters to render the text // QTextCodec *charset = selectCharset(m_charsets, htmlBody); // htmlPart->contentType()->setCharset(charset->name()); textPart->contentType()->setCharset("utf-8"); htmlPart->contentTransferEncoding()->setEncoding(KMime::Headers::CE8Bit); htmlPart->fromUnicodeString(htmlBody); multipartAlternative->addContent(htmlPart); return multipartAlternative; }
//From MailClient::send KMime::Message::Ptr createMessage( const QString &from, const QString &_to, const QString &cc, const QString &subject, const QString &body, bool hidden, bool bccMe, const QString &attachment/*, const QString &mailTransport */) { Q_UNUSED( hidden ); const bool outlookConformInvitation = false; QString userAgent = "libkolab"; // We must have a recipients list for most MUAs. Thus, if the 'to' list // is empty simply use the 'from' address as the recipient. QString to = _to; if ( to.isEmpty() ) { to = from; } kDebug() << "\nFrom:" << from << "\nTo:" << to << "\nCC:" << cc << "\nSubject:" << subject << "\nBody: \n" << body << "\nAttachment:\n" << attachment /*<< "\nmailTransport: " << mailTransport*/; // Now build the message we like to send. The message KMime::Message::Ptr instance // will be the root message that has 2 additional message. The body itself and // the attached cal.ics calendar file. KMime::Message::Ptr message = KMime::Message::Ptr( new KMime::Message ); message->contentTransferEncoding()->clear(); // 7Bit, decoded. // Set the headers message->userAgent()->fromUnicodeString(userAgent, "utf-8" ); message->from()->fromUnicodeString( from, "utf-8" ); message->to()->fromUnicodeString( to, "utf-8" ); message->cc()->fromUnicodeString( cc, "utf-8" ); if( bccMe ) { message->bcc()->fromUnicodeString( from, "utf-8" ); //from==me, right? } message->date()->setDateTime( KDateTime::currentLocalDateTime() ); message->subject()->fromUnicodeString( subject, "utf-8" ); if ( outlookConformInvitation ) { message->contentType()->setMimeType( "text/calendar" ); message->contentType()->setCharset( "utf-8" ); message->contentType()->setName( QLatin1String( "cal.ics" ), "utf-8" ); message->contentType()->setParameter( QLatin1String( "method" ), QLatin1String( "request" ) ); if ( !attachment.isEmpty() ) { KMime::Headers::ContentDisposition *disposition = new KMime::Headers::ContentDisposition( message.get() ); disposition->setDisposition( KMime::Headers::CDinline ); message->setHeader( disposition ); message->contentTransferEncoding()->setEncoding( KMime::Headers::CEquPr ); message->setBody( KMime::CRLFtoLF( attachment.toUtf8() ) ); } } else { // We need to set following 4 lines by hand else KMime::Content::addContent // will create a new Content instance for us to attach the main message // what we don't need cause we already have the main message instance where // 2 additional messages are attached. KMime::Headers::ContentType *ct = message->contentType(); ct->setMimeType( "multipart/mixed" ); ct->setBoundary( KMime::multiPartBoundary() ); ct->setCategory( KMime::Headers::CCcontainer ); // Set the first multipart, the body message. KMime::Content *bodyMessage = new KMime::Content; KMime::Headers::ContentDisposition *bodyDisposition = new KMime::Headers::ContentDisposition( bodyMessage ); bodyDisposition->setDisposition( KMime::Headers::CDinline ); bodyMessage->contentType()->setMimeType( "text/plain" ); bodyMessage->contentType()->setCharset( "utf-8" ); bodyMessage->contentTransferEncoding()->setEncoding( KMime::Headers::CEquPr ); bodyMessage->setBody( KMime::CRLFtoLF( body.toUtf8() ) ); message->addContent( bodyMessage ); // Set the sedcond multipart, the attachment. if ( !attachment.isEmpty() ) { KMime::Content *attachMessage = new KMime::Content; KMime::Headers::ContentDisposition *attachDisposition = new KMime::Headers::ContentDisposition( attachMessage ); attachDisposition->setDisposition( KMime::Headers::CDattachment ); attachMessage->contentType()->setMimeType( "text/calendar" ); attachMessage->contentType()->setCharset( "utf-8" ); attachMessage->contentType()->setName( QLatin1String( "cal.ics" ), "utf-8" ); attachMessage->contentType()->setParameter( QLatin1String( "method" ), QLatin1String( "request" ) ); attachMessage->setHeader( attachDisposition ); attachMessage->contentTransferEncoding()->setEncoding( KMime::Headers::CEquPr ); attachMessage->setBody( KMime::CRLFtoLF( attachment.toUtf8() ) ); message->addContent( attachMessage ); } } // Job done, attach the both multiparts and assemble the message. message->assemble(); return message; }