KIO
kbookmarkimporter_crash.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kbookmarkimporter_crash.h"
00022
00023 #include <kfiledialog.h>
00024 #include <kstringhandler.h>
00025 #include <klocale.h>
00026 #include <kdebug.h>
00027 #include <kstandarddirs.h>
00028 #include <qfile.h>
00029 #include <qdir.h>
00030 #include <qstring.h>
00031 #include <qtextcodec.h>
00032 #include <qset.h>
00033 #include <QtDBus/QtDBus>
00034
00035 #include <sys/types.h>
00036 #include <stddef.h>
00037 #include <dirent.h>
00038 #include <sys/stat.h>
00039
00040 typedef QMap<QString, QString> ViewMap;
00041
00042
00043 ViewMap KCrashBookmarkImporterImpl::parseCrashLog_noemit( const QString & filename, bool del )
00044 {
00045 static const int g_lineLimit = 16*1024;
00046
00047 QFile f( filename );
00048 ViewMap views;
00049
00050 if ( !f.open( QIODevice::ReadOnly ) )
00051 return views;
00052
00053 QByteArray s( g_lineLimit, 0 );
00054
00055 QTextCodec * codec = QTextCodec::codecForName( "UTF-8" );
00056 Q_ASSERT( codec );
00057 if ( !codec )
00058 return views;
00059
00060 while ( f.readLine( s.data(), g_lineLimit ) >=0 )
00061 {
00062 if ( s[s.length()-1] != '\n' )
00063 {
00064 kWarning() << "Crash bookmarks contain a line longer than " << g_lineLimit << ". Skipping.";
00065 continue;
00066 }
00067 QString t = codec->toUnicode( s.trimmed() );
00068 QRegExp rx( "(.*)\\((.*)\\):(.*)$" );
00069 rx.setMinimal( true );
00070 if ( !rx.exactMatch( t ) )
00071 continue;
00072 if ( rx.cap(1) == "opened" )
00073 views[rx.cap(2)] = rx.cap(3);
00074 else if ( rx.cap(1) == "close" )
00075 views.remove( rx.cap(2) );
00076 }
00077
00078 f.close();
00079
00080 if ( del )
00081 f.remove();
00082
00083 return views;
00084 }
00085
00086 QStringList KCrashBookmarkImporterImpl::getCrashLogs()
00087 {
00088 QSet<QString> activeLogs;
00089
00090 QStringList apps = QDBusConnection::sessionBus().interface()->registeredServiceNames();
00091 foreach ( const QString &clientId, apps )
00092 {
00093 if ( !clientId.startsWith( QLatin1String("org.kde.konqueror") ) )
00094 continue;
00095
00096 QDBusReply<QString> reply =
00097 QDBusInterface(clientId, "/KonqMain", "org.kde.Konqueror").call("crashLogfile");
00098
00099 if ( !reply.isValid() )
00100 continue;
00101
00102 activeLogs += reply;
00103 }
00104
00105 QDir d( KCrashBookmarkImporterImpl().findDefaultLocation() );
00106 d.setSorting( QDir::Time );
00107 d.setFilter( QDir::Files );
00108 d.setNameFilters( QStringList( "konqueror-crash-*.log" ) );
00109
00110 QFileInfoList list = d.entryInfoList();
00111 QListIterator<QFileInfo> it( list );
00112
00113 QStringList crashFiles;
00114
00115 int count = 0;
00116 while ( it.hasNext() && count < 20 )
00117 {
00118 count++;
00119 QString path = it.next().absoluteFilePath();
00120 bool stillAlive = activeLogs.contains( path );
00121 if ( !stillAlive )
00122 crashFiles << path;
00123 }
00124
00125 while ( it.hasNext() )
00126 {
00127 QFile::remove( it.next().absoluteFilePath() );
00128 }
00129
00130 return crashFiles;
00131 }
00132
00133 void KCrashBookmarkImporterImpl::parse()
00134 {
00135 QSet<QString> signatureSet;
00136 const QStringList crashFiles = KCrashBookmarkImporterImpl::getCrashLogs();
00137 int count = 1;
00138 for ( QStringList::ConstIterator it = crashFiles.begin(); it != crashFiles.end(); ++it )
00139 {
00140 const ViewMap views = parseCrashLog_noemit( *it, m_shouldDelete );
00141 QString signature;
00142 for ( ViewMap::ConstIterator vit = views.begin(); vit != views.end(); ++vit )
00143 signature += '|'+vit.value();
00144 if (signatureSet.contains(signature))
00145 {
00146
00147 QFile::remove(*it);
00148 continue;
00149 }
00150
00151 signatureSet.insert(signature);
00152
00153 int outerFolder = ( crashFiles.count() > 1 ) && (views.count() > 0);
00154 if ( outerFolder )
00155 emit newFolder( QString("Konqueror Window %1").arg(count++), false, "" );
00156 for ( ViewMap::ConstIterator vit = views.begin(); vit != views.end(); ++vit )
00157 emit newBookmark( vit.value(), vit.value(), QString("") );
00158 if ( outerFolder )
00159 emit endFolder();
00160 }
00161 }
00162
00163 QString KCrashBookmarkImporter::crashBookmarksDir()
00164 {
00165 static KCrashBookmarkImporterImpl *p = 0;
00166 if (!p)
00167 p = new KCrashBookmarkImporterImpl;
00168 return p->findDefaultLocation();
00169 }
00170
00171 void KCrashBookmarkImporterImpl::setShouldDelete( bool shouldDelete )
00172 {
00173 m_shouldDelete = shouldDelete;
00174 }
00175
00176 void KCrashBookmarkImporter::parseCrashBookmarks( bool del )
00177 {
00178 KCrashBookmarkImporterImpl importer;
00179 importer.setFilename( m_fileName );
00180 importer.setShouldDelete( del );
00181 importer.setupSignalForwards( &importer, this );
00182 importer.parse();
00183 }
00184
00185 QString KCrashBookmarkImporterImpl::findDefaultLocation( bool ) const
00186 {
00187 return KStandardDirs::locateLocal( "tmp", "" );
00188 }
00189
00190 #include "kbookmarkimporter_crash.moc"