main.cpp 6.76 KB
Newer Older
Lukas Appelhans's avatar
Lukas Appelhans committed
1
/*
2 3 4 5 6 7 8 9 10 11 12 13 14 15
 * This file is part of the Chakra project
 * Source of the tool akabei-clean-cache

   Copyright (C) 2010 Lisa Vitolo <shainer@chakra-project.org>

   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.
*/

#include <QSettings>
#include <QStringList>
#include <QCoreApplication>
16
#include <QTextStream>
17 18 19 20 21 22

#include <akabeicache.h>
#include <akabeibackend.h>

using namespace std;

23
const QString CACHEDIR = "/var/cache/akabei";
24
const QString DATABASEDIR = "/var/lib/akabei";
25

26 27 28 29
/*
 * Attempt to read a cache directory from the default configuration file
 */
QString readCacheDirFromConfig()
Lukas Appelhans's avatar
Lukas Appelhans committed
30
{
31
    QSettings settings("/etc/akabei.conf", QSettings::NativeFormat);
Lukas Appelhans's avatar
Lukas Appelhans committed
32

33
    if (!QFile::exists(settings.fileName())) {
34
        QTextStream err(stderr);
35 36
        err << QObject::tr("[!!] Configuration file \"%1\" doesn't exist.").arg(settings.fileName()) << endl;
        err << QObject::tr("Please create one before continuing.") << endl;
37 38
        exit(-1);
    }
Lukas Appelhans's avatar
Lukas Appelhans committed
39

40 41 42
    if (settings.contains("CacheDir")) {
        return settings.value("CacheDir").toString();
    }
Lukas Appelhans's avatar
Lukas Appelhans committed
43

44
    return CACHEDIR;
45 46
}

47 48
QString readDatabaseDirFromConfig()
{
49
    QSettings settings("/etc/akabei.conf", QSettings::NativeFormat);
50 51 52

    if (!QFile::exists(settings.fileName())) {
        QTextStream err(stderr);
53 54
        err << QObject::tr("[!!] Configuration file \"%1\" doesn't exist.").arg(settings.fileName()) << endl;
        err << QObject::tr("Please create one before continuing.") << endl;
55 56 57 58 59 60 61 62 63 64
        exit(-1);
    }

    if (settings.contains("DatabaseDir")) {
        return settings.value("DatabaseDir").toString();
    }

    return DATABASEDIR;
}

65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
void helpMessage()
{
    QTextStream out( stdout );
    
    out << QObject::tr(":: Akabei's cache cleaner tool") << endl;
    out << endl;
    out << "-c, --cachedir <path>" << endl;
    out << "    " << QObject::tr("Sets cache directory") << endl;
    out << "-d, --databasedir <path>" << endl;
    out << "    " << QObject::tr("Sets database directory") << endl;
    out << "-k, --keep-package <package>" << endl;
    out << "    " << QObject::tr("Never delete <package> from cache") << endl;
    out << "-o, --clean-old" << endl;
    out << "    " << QObject::tr("Clean the oldest packages in cache") << endl;
    out << "-u, --clean-unused" << endl;
    out << "    " << QObject::tr("Clean the least used packages in cache") << endl;
    out << "-a, --clean-all" << endl;
    out << "    " << QObject::tr("Clean all cache (default)") << endl;
    out << "-n, --clean-not-installed" << endl;
    out << "    " << QObject::tr("Clean all uninstalled packages") << endl;
}

87 88 89 90 91 92
int main(int argc, char **argv)
{
    /*
     * This lines are needed to tell QSettings where the config file is located
     */
    QCoreApplication::setOrganizationName("The Chakra Project");
AlmAck's avatar
AlmAck committed
93
    QCoreApplication::setOrganizationDomain("chakraos.org");
94
    QCoreApplication::setApplicationName("Akabei");
95
    QCoreApplication app(argc, argv);
Lukas Appelhans's avatar
Lukas Appelhans committed
96

97 98 99
    /*
     * Command line wins over configuration file
     */
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
    QString cachedir, databasedir;
    QStringList keepPackages;
    Akabei::Cache::MaxSizePolicy policy = Akabei::Cache::CleanAll;
    
    /*
     * Since both Old and Unused can be triggered together, keep track of whether we already set one "part",
     * so that we can use the correct flag if the second "part" is set too
     */
    bool isOldOrUnused = false;
    
    for (int i = 0; i < argc; i++) {
        QString arg( argv[i] );
        
        /*
         * Non-options are already treated when required
         */
        if (!arg.startsWith("-")) {
            continue;
        }
        
        if (arg == "-h" || arg == "--help") {
            helpMessage();
            return 0;
        }
        
        if (arg == "--cachedir" || arg == "-c") {
            cachedir = (i < argc - 1) ? QString::fromAscii(argv[i + 1]) : QString();
        } else if (arg == "--databasedir" || arg == "-d") {
            databasedir = (i < argc - 1) ? QString::fromAscii(argv[i + 1]) : QString();
        } else if (arg == "-k" || arg == "--keep-package") {
            
            /*
             * Take all the following arguments for this option, until we find another option or we have no more args.
             * Also, args can be in a single string, but separated by commas.
             */ 
            for (int j = i + 1; j < argc && argv[j][0] != '-'; j++) {
                keepPackages << QString::fromAscii(argv[j]).split(",");
            }
            
        } else if (arg == "-o" || arg == "--clean-old") {
            
            if (isOldOrUnused) {
                policy = Akabei::Cache::CleanOldAndUnused;
            } else {
                policy = Akabei::Cache::CleanOld;
                isOldOrUnused = true;
            }
            
        } else if (arg == "-u" || arg == "--clean-unused") {
            
            if (isOldOrUnused) {
                policy = Akabei::Cache::CleanOldAndUnused;
            } else {
                policy = Akabei::Cache::CleanUnused;
                isOldOrUnused = true;
            }
            
        } else if (arg == "-a" || arg == "--clean-all") {
            policy = Akabei::Cache::CleanAll;
        } else if (arg == "-n" || arg == "--clean-not-installed") {
            policy = Akabei::Cache::CleanNotInstalled;
        }
    }
    
    /* Command line has a higher priority than the configuration file */
    if (cachedir.isEmpty()) {
166 167
        cachedir = readCacheDirFromConfig();
    }
168
    if (databasedir.isEmpty()) {
169 170 171
        databasedir = readDatabaseDirFromConfig();
    }

172 173
    QTextStream err(stderr);
    QDir cd(cachedir);
174
    QDir dd(databasedir);
Lukas Appelhans's avatar
Lukas Appelhans committed
175

176
    if (!cd.exists()) {
177 178 179 180 181 182 183 184
        err << QObject::tr("[!!] Directory \"%1\" doesn't exist.").arg(cachedir) << endl;
        err << QObject::tr("Please select another one using the --cachedir option.") << endl;
        return -1;
    }
    
    if (!dd.exists()) {
        err << QObject::tr("[!!] Directory \"%1\" doesn't exist.").arg(databasedir) << endl;
        err << QObject::tr("Please select another one using the --databasedir option.") << endl;
185 186
        return -1;
    }
Lukas Appelhans's avatar
Lukas Appelhans committed
187

188
    QSettings settings("/etc/akabei.conf", QSettings::NativeFormat);
189 190 191 192 193 194
    settings.beginGroup("cache");
    if (!settings.value("KeepPackages").isNull()) {
        keepPackages.append(settings.value("KeepPackages").toString().split(' '));
    }
    keepPackages.removeDuplicates();
    settings.endGroup();
Lukas Appelhans's avatar
Lukas Appelhans committed
195

196
    Akabei::Cache cache(cachedir, databasedir, keepPackages);
Lukas Appelhans's avatar
Lukas Appelhans committed
197
    cache.cleanCache(policy);
198
    if (!cache.errorString().isEmpty()) {
AlmAck's avatar
AlmAck committed
199
        err << QObject::tr("[!!] An error occurred while performing cache cleaning: ") << cache.errorString() << endl;
200 201
        return -1;
    }
Lukas Appelhans's avatar
Lukas Appelhans committed
202

203 204
    return 0;
}