Example #1
0
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;
}
Example #3
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 );
}
Example #5
0
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;
}
Example #8
0
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
}
Example #9
0
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;
}