You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdesdk/kbugbuster/backend/bugdetails.cpp

269 lines
8.3 KiB

#include "bugdetails.h"
#include "bugdetailsimpl.h"
#include <tqstringlist.h>
#include <kdebug.h>
#include <kmdcodec.h>
#include <kmessagebox.h>
#include <tqregexp.h>
BugDetails::BugDetails()
{
}
BugDetails::BugDetails( BugDetailsImpl *impl ) :
m_impl( impl )
{
}
BugDetails::BugDetails( const BugDetails &other )
{
(*this) = other;
}
BugDetails &BugDetails::operator=( const BugDetails &rhs )
{
m_impl = rhs.m_impl;
return *this;
}
BugDetails::~BugDetails()
{
}
TQString BugDetails::version() const
{
if ( !m_impl )
return TQString();
return m_impl->version;
}
TQString BugDetails::source() const
{
if ( !m_impl )
return TQString();
return m_impl->source;
}
TQString BugDetails::compiler() const
{
if ( !m_impl )
return TQString();
return m_impl->compiler;
}
TQString BugDetails::os() const
{
if ( !m_impl )
return TQString();
return m_impl->os;
}
TQDateTime BugDetails::submissionDate() const
{
if ( !m_impl ) return TQDateTime();
if ( m_impl->parts.count() > 0 ) {
return m_impl->parts.last().date;
}
return TQDateTime();
}
int BugDetails::age() const
{
if ( !m_impl )
return 0;
return submissionDate().daysTo( TQDateTime::tqcurrentDateTime() );
}
BugDetailsPart::List BugDetails::parts() const
{
if ( !m_impl )
return BugDetailsPart::List();
return m_impl->parts;
}
TQValueList<BugDetailsImpl::AttachmentDetails> BugDetails::attachmentDetails() const
{
if ( m_impl )
return m_impl->attachments;
else
return TQValueList<BugDetailsImpl::AttachmentDetails>();
}
void BugDetails::addAttachmentDetails( const TQValueList<BugDetailsImpl::AttachmentDetails>& attch )
{
if ( m_impl )
m_impl->attachments = attch;
}
TQValueList<BugDetails::Attachment> BugDetails::extractAttachments() const
{
TQValueList<BugDetails::Attachment> lst;
if ( !m_impl )
return lst;
BugDetailsPart::List parts = m_impl->parts;
for ( BugDetailsPart::List::ConstIterator it = parts.begin(); it != parts.end(); ++it ) {
lst += extractAttachments( (*it).text );
}
return lst;
}
//#define DEBUG_EXTRACT
TQValueList<BugDetails::Attachment> BugDetails::extractAttachments( const TQString& text )
{
TQValueList<BugDetails::Attachment> lst;
TQStringList lines = TQStringList::split( '\n', text );
#ifdef DEBUG_EXTRACT
kdDebug() << k_funcinfo << lines.count() << " lines." << endl;
#endif
TQString boundary;
for ( TQStringList::Iterator it = lines.begin() ; it != lines.end() ; ++it )
{
#ifdef DEBUG_EXTRACT
kdDebug() << "Line: " << *it << endl;
#endif
if ( (*it).startsWith( " Content-Type" ) ) // ## leading space comes from khtml
{
#ifdef DEBUG_EXTRACT
//kdDebug() << "BugDetails::extractAttachments going back, looking for empty or boundary=" << boundary << endl;
#endif
// Rewind until last empty line
TQStringList::Iterator rit = it;
for ( ; rit != lines.begin() ; --rit ) {
TQString line = *rit;
if ( line.endsWith( "<br />" ) )
line = line.left( line.length() - 6 );
while ( !line.isEmpty() && line[0] == ' ' )
line.remove( 0, 1 );
#ifdef DEBUG_EXTRACT
kdDebug() << "Back: '" << line << "'" << endl;
#endif
if ( line.isEmpty() ) {
++rit; // boundary is next line
boundary = *rit;
if ( boundary.endsWith( "<br />" ) )
boundary = boundary.left( boundary.length() - 6 );
if ( boundary[0] == ' ' )
boundary.remove( 0, 1 );
kdDebug() << "BugDetails::extractAttachments boundary=" << boundary << endl;
break;
}
if ( line == boundary )
break;
}
// Forward until next empty line (end of headers) - and parse filename
TQString filename;
TQString encoding;
rit = it;
for ( ; rit != lines.end() ; ++rit ) {
TQString header = *rit;
if ( header.endsWith( "<br />" ) )
header = header.left( header.length() - 6 );
if ( header[0] == ' ' )
header.remove( 0, 1 );
#ifdef DEBUG_EXTRACT
kdDebug() << "Header: '" << header << "'" << endl;
#endif
if ( header.isEmpty() )
break;
if ( header.startsWith( "Content-Disposition:" ) )
{
#ifdef DEBUG_EXTRACT
kdDebug() << "BugDetails::extractAttachments found header " << *rit << endl;
#endif
// Taken from libkdenetwork/kmime_headers.cpp
int pos=header.tqfind("filename=", 0, false);
TQString fn;
if(pos>-1) {
pos+=9;
fn=header.mid(pos, header.length()-pos);
if ( fn.startsWith( "\"" ) && fn.endsWith( "\"" ) )
fn = fn.mid( 1, fn.length() - 2 );
//filename=decodeRFC2047String(fn, &e_ncCS, defaultCS(), forceCS());
filename = fn; // hack
kdDebug() << "BugDetails::extractAttachments filename=" << filename << endl;
}
}
else if ( header.startsWith( "Content-Transfer-Encoding:" ) )
{
encoding = header.mid( 26 ).lower();
while ( encoding[0] == ' ' )
encoding.remove( 0, 1 );
kdDebug() << "BugDetails::extractAttachments encoding=" << encoding << endl;
}
} //for
if ( rit == lines.end() )
break;
it = rit;
if ( rit != lines.end() && !filename.isEmpty() )
{
++it;
if ( it == lines.end() )
break;
// Read encoded contents
TQString contents;
for ( ; it != lines.end() ; ++it )
{
TQString line = *it;
if ( line.endsWith( "</tt>" ) )
line = line.left( line.length() - 5 );
if ( line.endsWith( "<br />" ) ) // necessary for the boundary check
line = line.left( line.length() - 6 );
while ( !line.isEmpty() && line[0] == ' ' )
line.remove( 0, 1 );
if ( line.isEmpty() || line == boundary ) // end of attachment
break;
if ( line == boundary+"--" ) // end of last attachment
{
boundary = TQString();
break;
}
contents += line; // no newline, because of linebreaking between <br and />
}
contents = contents.tqreplace( TQRegExp("<br */>"), TQString() );
#ifdef DEBUG_EXTRACT
kdDebug() << "BugDetails::extractAttachments contents=***\n" << contents << "\n***" << endl;
#endif
kdDebug() << "BugDetails::extractAttachments creating attachment " << filename << endl;
Attachment a;
if ( encoding == "base64" )
KCodecs::base64Decode( contents.local8Bit(), a.contents /*out*/ );
else
//KCodecs::uudecode( contents.local8Bit(), a.contents /*out*/ );
KMessageBox::information( 0, i18n("Attachment %1 could not be decoded.\nEncoding: %2").tqarg(filename).tqarg(encoding) );
#ifdef DEBUG_EXTRACT
kdDebug() << "Result: ***\n" << TQCString( a.contents.data(), a.contents.size()+1 ) << "\n*+*" << endl;
#endif
a.filename = filename;
lst.append(a);
if ( it == lines.end() )
break;
}
}
}
#ifdef DEBUG_EXTRACT
kdDebug() << "BugDetails::extractAttachments returning " << lst.count() << " attachments for this part." << endl;
#endif
return lst;
}
bool BugDetails::operator==( const BugDetails &rhs )
{
return m_impl == rhs.m_impl;
}
/**
* vim:ts=4:sw=4:et
*/