release 0.6.6
[fapman] / aaptinterface.cpp
index b27304a..3f4546d 100644 (file)
@@ -42,6 +42,10 @@ AAptInterface::AAptInterface(QObject* parent = 0) : QObject(parent)
        iNeedDateRefresh = true;
        iNeedDpkgRefresh = true;
        iSkipRefreshListAndDates = false;
+       iLastListUpdate.setTime_t(0);
+       iLastDpkgUpdate.setTime_t(0);
+
+       iDataReadBuffer = new char[KDataReadBufferSize];
 
        iProcAptGetUpdate = new QProcess(this);
        iProcAptGetSimulate = new QProcess(this);
@@ -101,6 +105,8 @@ AAptInterface::~AAptInterface()
                iProcAptGetInstall->kill();
        if( iProcAptGetClean->state() != QProcess::NotRunning )
                iProcAptGetClean->kill();
+
+       delete iDataReadBuffer;
 }
 
 void AAptInterface::addQueuedOperation(interfaceMode mode_)
@@ -533,6 +539,10 @@ QString AAptInterface::finishProcessCommonErrorMessages(QByteArray& output)
                msg = "Some of your packages have unmet dependencies which could not be fixed. See the log for details.";
        } else if( output.contains("E: The method driver") ) {
                msg = "Apt failed to find a suitable method driver. One or more of your repositories might have an invalid URL.";
+       } else if( output.contains("E: Invalid record in the preferences file") ) {
+               msg = "Invalid record in the apt preferences file.";
+       } else if( output.contains("E: Malformed line") && output.contains("in source list") ) {
+               msg = "Malformed line in sources list. Check your repository settings.";
        }
 
        return msg;
@@ -744,15 +754,26 @@ void AAptInterface::uiUpdaterAptGetUpdate()
                return;
 
        QStringList lines = QString( data.trimmed() ).split('\n');
+       QString infoline;
 
        for( int i=0; i<lines.count(); i++ )
        {
                if( lines.at(i).startsWith("Get:") || lines.at(i).startsWith("Hit ") )
-                       iCatalogCounter++;
+               {
+                       iCatalogCounter++;                      
+               }
+               infoline = lines.at(i).trimmed();
        }
+       //if( infoline.isEmpty() )
+               //infoline = "arstus";
+
        //iUiDimmer->updateText( QString("Updating catalogs (%1)").arg(iCatalogCounter) );
        //qDebug() << iCatalogCounter << iCatalogsTotal;
-       iUiDimmer->setProgress( iCatalogCounter*100/iCatalogsTotal );
+
+       //iUiDimmer->updateText("Updating catalogs<br><font size=\"-1\">" + infoline + "</font>");
+
+       if( iCatalogsTotal > 0 )
+               iUiDimmer->setProgress( iCatalogCounter*100/iCatalogsTotal );
 }
 
 void AAptInterface::uiUpdaterAptGetInstall()
@@ -845,7 +866,7 @@ void AAptInterface::uiUpdaterAptGetInstall()
 
 void AAptInterface::progressCheckTimerCallback()
 {
-       if( iAptGetCurrentDownloadFileName=="" )
+       if( iAptGetCurrentDownloadFileName.isEmpty() )
                return;
 
        qint64 prevsize = iAptGetCurrentFileDownloadSize;
@@ -902,7 +923,7 @@ QByteArray AAptInterface::readLogFile()
                own.close();
        }
 
-       if( log=="" )
+       if( log.isEmpty() )
                log = "The log is empty";
 
        return log;
@@ -970,7 +991,7 @@ void AAptInterface::readRepositoryInfo()
                while(!names.atEnd() && c<iRepositories.count())
                {
                        QString line = names.readLine().trimmed();
-                       if( line.trimmed()!="" )
+                       if( !line.trimmed().isEmpty() )
                        iRepositories.at(c)->setName( line.trimmed() );
                        c++;
                }
@@ -1135,7 +1156,7 @@ void AAptInterface::startPkgListRead()
        quint64 totaldatasize = 0;
        quint64 currentreaddata = 0;
        quint64 lastupdatedata = 0;
-       quint64 updateinterval = 1000000;
+       quint64 updateinterval = 2000000;
        if( iNeedListRefresh && !iSkipRefreshListAndDates ) {
                for( int i=0; i<files.count(); i++ )
                {
@@ -1181,7 +1202,6 @@ void AAptInterface::startPkgListRead()
 
                                while (!db.atEnd() && !iTerminated) {
                                        Package* newpkg = ReadNextPackage(db, currentreaddata);
-                                       //qDebug() << "read" << currentreaddata << "of" << totaldatasize;
                                        if( iUiDimmer && currentreaddata >= lastupdatedata+updateinterval ) {
                                                iUiDimmer->setProgress( currentreaddata*100/totaldatasize );
                                                lastupdatedata = currentreaddata;
@@ -1233,6 +1253,7 @@ void AAptInterface::startPkgListRead()
 
                iNeedListRefresh = false;
                iNeedDateRefresh = true;
+               iLastListUpdate = QDateTime::currentDateTime();
        }
 
 // read dpkg database (installed packages)
@@ -1264,7 +1285,7 @@ void AAptInterface::startPkgListRead()
                        }
                        pkgcount_dpkg++;
                        if( newpkg ) {
-                               if( newpkg->isInstalled() ) {
+                               if( newpkg->isInstalled() && !newpkg->name().isEmpty() ) {
                                        iPackagesInstalled.insert(newpkg->name(), newpkg);
                                } else {
                                        delete newpkg;
@@ -1286,6 +1307,7 @@ void AAptInterface::startPkgListRead()
                        return;
                }
                iNeedDpkgRefresh = false;
+               iLastDpkgUpdate = QDateTime::currentDateTime();
        }
 
        logToFile( QString("Finished reading package lists") );
@@ -1296,6 +1318,7 @@ void AAptInterface::startPkgListRead()
        }
 
        readBlacklist();
+       readPinnedPackages();
 
        communicateStatusToUi(true, "Operation finished", "Package data read");
        iCanCancel = false;
@@ -1309,15 +1332,19 @@ Package* AAptInterface::ReadNextPackage(QFile& f, quint64& currentreaddata)
        Package* pkg = new Package("", this);
 
        bool pkgready = false;
+
+       // this is faster than directly reading to QByteArray...
+       QByteArray line;
        while( !pkgready && !f.atEnd() ) {
-               QByteArray line = f.readLine();
+               f.readLine(iDataReadBuffer,KDataReadBufferSize);
+               line = iDataReadBuffer;
                currentreaddata += line.size();
                if( processPackageDataLine(pkg,line) ) {
                        pkgready = true;
                }
        }
 
-       if( pkg->name() != "" && pkg->isInstalled() ) {
+       if( !pkg->name().isEmpty() && pkg->isInstalled() ) {
                QFileInfo f( KDpkgInfoDir + "/" + pkg->name() + ".list" );
                if( f.exists() )
                        pkg->setDate( f.lastModified() );
@@ -1325,7 +1352,8 @@ Package* AAptInterface::ReadNextPackage(QFile& f, quint64& currentreaddata)
 
        pkg->updateStatus();
 
-       if( pkg->name() == "" ) {
+       if( pkg->name().isEmpty() ) {
+               qDebug() << "null name package!";
                delete pkg;
                pkg = 0;
        }
@@ -1334,12 +1362,37 @@ Package* AAptInterface::ReadNextPackage(QFile& f, quint64& currentreaddata)
 
 bool AAptInterface::processPackageDataLine(Package*& pkg, QByteArray& line)
 {
-       if( !line.startsWith(' ') && !line.startsWith('\t') )
-               line = line.trimmed();
-       if( line.trimmed()=="" )
+       if( line.isEmpty() || line=="\n" )
+       {
                return true;
+       }
+
+       else if( iMultiLine == MultiLineDesc ) {
+               if( (line.startsWith(' ') || line.startsWith('\t')) && !line.trimmed().isEmpty() ) {
+                       if( line.trimmed()!="." )
+                               pkg->appendDescLong( line.trimmed() + "\n" );
+                       else
+                               pkg->appendDescLong( "\n" );
+               } else {
+                       iMultiLine = MultiLineNone;
+               }
+       }
+       else if( iMultiLine == MultiLineIcon ) {
+               if( (line.startsWith(' ') || line.startsWith('\t')) && !line.trimmed().isEmpty() ) {
+                       pkg->appendIconData( line.trimmed() );
+               } else {
+                       iMultiLine = MultiLineNone;
+               }
+       }
+       else if( iMultiLine == MultiLineUpgradeDesc ) {
+               if( (line.startsWith(' ') || line.startsWith('\t')) && !line.trimmed().isEmpty() ) {
+                       pkg->appendUpgradeDescription( line.trimmed() + "\n" );
+               } else {
+                       iMultiLine = MultiLineNone;
+               }
+       }
 
-       if( line.startsWith("Package:") )
+       else if( line.startsWith("Package:") )
        {
                pkg->setName( line.mid(8).trimmed() );
                iMultiLine=MultiLineNone;
@@ -1387,18 +1440,10 @@ bool AAptInterface::processPackageDataLine(Package*& pkg, QByteArray& line)
        {
                pkg->appendPreDepends( line.mid(12).trimmed() );
        }
-       else if( line.startsWith("Provides:") )
-       {
-               pkg->appendProvides( line.mid(9).trimmed() );
-       }
        else if( line.startsWith("Replaces:") )
        {
                pkg->appendReplaces( line.mid(9).trimmed() );
        }
-       else if( line.startsWith("Breaks:") )
-       {
-               pkg->appendBreaks( line.mid(7).trimmed() );
-       }
        else if( line.startsWith("Recommends:") )
        {
                pkg->appendRecommends( line.mid(11).trimmed() );
@@ -1407,33 +1452,20 @@ bool AAptInterface::processPackageDataLine(Package*& pkg, QByteArray& line)
        {
                pkg->appendSuggests( line.mid(9).trimmed() );
        }
-
-       if( iMultiLine == MultiLineDesc ) {
-               if( (line.startsWith(' ') || line.startsWith('\t')) && line.trimmed()!="" ) {
-                       if( line.trimmed()!="." )
-                               pkg->appendDescLong( line.trimmed() + "\n" );
-                       else
-                               pkg->appendDescLong( "\n" );
-               } else {
-                       iMultiLine = MultiLineNone;
-               }
+       else if( line.startsWith("Provides:") )
+       {
+               pkg->appendProvides( line.mid(9).trimmed() );
        }
-       else if( iMultiLine == MultiLineIcon ) {
-               if( (line.startsWith(' ') || line.startsWith('\t')) && line.trimmed()!="" ) {
-                       pkg->appendIconData( line.trimmed() );
-               } else {
-                       iMultiLine = MultiLineNone;
-               }
+       else if( line.startsWith("Breaks:") )
+       {
+               pkg->appendBreaks( line.mid(7).trimmed() );
        }
-       else if( iMultiLine == MultiLineUpgradeDesc ) {
-               if( (line.startsWith(' ') || line.startsWith('\t')) && line.trimmed()!="" ) {
-                       pkg->appendUpgradeDescription( line.trimmed() + "\n" );
-               } else {
-                       iMultiLine = MultiLineNone;
-               }
+       else if( line.startsWith("Maintainer:") )
+       {
+               pkg->setMaintainer( line.mid(11).trimmed() );
        }
 
-       if( line.startsWith("Description:") )
+       else if( line.startsWith("Description:") )
        {
                pkg->setDescShort( line.mid(12).trimmed() );
                iMultiLine = MultiLineDesc;
@@ -1596,6 +1628,13 @@ void AAptInterface::startFetchDates()
        }
 
        QNetworkAccessManager* nam = new QNetworkAccessManager(this);
+
+       if( iSettings->qsettings()->value("use_proxies").toBool() && !iSettings->qsettings()->value("http_proxy").toString().isEmpty() )
+       {
+                QNetworkProxy proxy = Settings::createProxyFromString( iSettings->qsettings()->value("http_proxy").toString() );
+                nam->setProxy(proxy);
+       }
+
        iCanCancel = true;
 
        int count = 0;
@@ -1637,7 +1676,7 @@ void AAptInterface::startFetchDates()
        {
                fe.next();
 
-               if( updProgress >=10 ) {
+               if( updProgress >=20 ) {
                        iUiDimmer->setProgress( count*100/fetchable.count() );
                        updProgress=0;
                }
@@ -1694,7 +1733,7 @@ void AAptInterface::startFetchDates()
                }
        }
        while( iDateRequestsWaiting>0 ) {
-               if( updProgress >=10 ) {
+               if( updProgress >=20 ) {
                        iUiDimmer->setProgress( count*100/fetchable.count() );
                        updProgress=0;
                }
@@ -1842,6 +1881,47 @@ bool AAptInterface::dateCacheExists()
        return f.exists();
 }
 
+void AAptInterface::readPinnedPackages()
+{
+       QFile f(KAptPreferencesFile);
+       if( !f.exists() )
+               return;
+
+       bool warnAllPinned = false;
+       if( f.open(QIODevice::ReadOnly | QIODevice::Text ) )
+       {
+               qDebug() << "apt preferences exist: reading pinned packages";
+               int pinned_packages = 0;
+               while( !f.atEnd() )
+               {
+                       QString line = f.readLine().trimmed();
+
+                       if( line=="Package: *" || line=="Package:*")
+                               warnAllPinned = true;
+
+                       if( line.startsWith("Package:") ) {
+                               pinned_packages++;
+                               QString pkg = line.mid(8).trimmed();
+                               Package* pkg_i = iPackagesInstalled.value(pkg,0);
+                               if( pkg_i ) {
+                                       pkg_i->setPinned(true);
+                               }
+                               Package* pkg_a = iPackagesAvailable.value(pkg,0);
+                               if( pkg_a ) {
+                                       pkg_a->setPinned(true);
+                               }
+                       }
+               }
+               f.close();
+               qDebug() << "read" << pinned_packages << "pinned packages";
+       }
+
+       if( warnAllPinned ) {
+               iMainWindow->notifyDialog("Warning","You have pinned packages with '*' in apt preferences. It is strongly recommended to "
+                                                                 "remove such settings as they can result in unexpected behavior of Faster Application Manager.");
+       }
+}
+
 bool AAptInterface::loadInstallFiles(QStringList files_)
 {
        qDebug() << files_;