queryoperation.cpp 12.5 KB
Newer Older
Lukas Appelhans's avatar
Lukas Appelhans committed
1 2 3 4 5 6 7 8 9 10 11 12 13
/* This file is part of the Chakra project

   Copyright (C) 2011 Lukas Appelhans <l.appelhans@gmx.de>

   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 "queryoperation.h"

#include <akabeibackend.h>
Lukas Appelhans's avatar
Lukas Appelhans committed
14
#include <akabeigroup.h>
Lukas Appelhans's avatar
Lukas Appelhans committed
15
#include <akabeidatabase.h>
Lukas Appelhans's avatar
Lukas Appelhans committed
16
#include <akabeiconfig.h>
Lukas Appelhans's avatar
Lukas Appelhans committed
17 18
#include <klocale.h>
#include <QTextStream>
Lukas Appelhans's avatar
Lukas Appelhans committed
19
#include <kio/global.h>
Lukas Appelhans's avatar
Lukas Appelhans committed
20
#include <kdebug.h>
Lukas Appelhans's avatar
Lukas Appelhans committed
21
#include <QDate>
Lukas Appelhans's avatar
Lukas Appelhans committed
22 23
#include <QFile>
#include <QDir>
Lukas Appelhans's avatar
Lukas Appelhans committed
24
#include <QCoreApplication>
Lukas Appelhans's avatar
Lukas Appelhans committed
25 26

QueryOperation::QueryOperation(QObject * parent)
Lisa's avatar
Lisa committed
27
    : QObject(parent)
Lukas Appelhans's avatar
Lukas Appelhans committed
28 29 30 31 32 33 34 35 36
{

}

QueryOperation::~QueryOperation()
{

}

37
void QueryOperation::start(APM::OperationName operation, QHash<APM::OptionName, AkabeiOption> options, QStringList args)
Lukas Appelhans's avatar
Lukas Appelhans committed
38
{
39 40
    if (operation == APM::ShowInformationLocal) {
        if (options.contains(APM::QueryPackageFile)) {
41
            showInformation(QList<Akabei::Package*>() << Akabei::Backend::instance()->loadPackageFromFile(args.first()));
42
        } else {
Lukas Appelhans's avatar
Lukas Appelhans committed
43
            showInformation(Akabei::Backend::instance()->localDatabase()->searchPackages(args.first(), Akabei::SearchNameEqual));
44
            //CHange back to searchPackages when we have sorted results after Name and description
45
        }
46
    } else if (operation == APM::ShowPackagesOfGroupLocal) {
Lisa's avatar
Lisa committed
47 48
        connect(Akabei::Backend::instance(), SIGNAL(queryGroupsCompleted(QUuid, QList<Akabei::Group*>)),
                SLOT(showGroup(QUuid, QList<Akabei::Group*>)));
49
        Akabei::Backend::instance()->localDatabase()->queryGroups("SELECT * FROM groups WHERE Name LIKE \"" + args.first() + "\"");
50 51
    } else if (operation == APM::ShowChangelog) {
        if (options.contains(APM::QueryPackageFile)) {
52
            showChangelog(QList<Akabei::Package*>() << Akabei::Backend::instance()->loadPackageFromFile(args.first()));
53
        } else {
54
            showChangelog(Akabei::Backend::instance()->localDatabase()->searchPackages(args.first()));
55
        }
56
    } else if (operation == APM::ShowInstalledAsDeps || operation == APM::ShowInstalledExplicitely) {
Lukas Appelhans's avatar
Lukas Appelhans committed
57
        QString query = "SELECT * FROM packages WHERE";
58
        if (!args.isEmpty()) // TODO: vedi un po' qua che vuol dire
Lukas Appelhans's avatar
Lukas Appelhans committed
59
            query = query + " Name LIKE \"" + args.first() + "\" AND";
60 61
        if (operation == APM::ShowInstalledAsDeps)
            query = query + " InstallReason LIKE 0";// + QString((int)Akabei::Package::InstalledAsDependencyReason);
62
        else
Lukas Appelhans's avatar
Lukas Appelhans committed
63
            query = query + " InstallReason LIKE " + QString::number((int)Akabei::Package::ExplicitlyInstalledReason);
Lukas Appelhans's avatar
Lukas Appelhans committed
64
        showInstalledAsDeps(Akabei::Backend::instance()->localDatabase()->queryPackages(query));
65 66
    } else if (operation == APM::CheckFiles) {
        if (options.contains(APM::QueryPackageFile)) {
67
            checkFiles(QList<Akabei::Package*>() << Akabei::Backend::instance()->loadPackageFromFile(args.first()));
68
        } else {
69
            checkFiles(Akabei::Backend::instance()->localDatabase()->searchPackages(args.first()));
70
        }
71
    } else if (operation == APM::SearchLocal) {
Lukas Appelhans's avatar
Lukas Appelhans committed
72 73 74 75
        if (args.isEmpty())
            showLocalPackages(QString());
        else
            showLocalPackages(args.first());
76
    } else if (operation == APM::ShowOwner) {
77
        showOwner(args.first());
78 79 80
    } else if (operation == APM::SearchLocal) {
        showLocalQuery(Akabei::Backend::instance()->localDatabase()->searchPackages(args.first(), Akabei::SearchNameEqual));
    } else if (operation == APM::ShowNotRequired) {
Lukas Appelhans's avatar
Lukas Appelhans committed
81
        showNotRequired();
82
    } else if (operation == APM::ShowUpgradeable) {
Lukas Appelhans's avatar
Lukas Appelhans committed
83
        showUpgradeable();
84
    } else {
85 86
        QTextStream err(stderr);
        err << "akabei: Operation not supported yet" << endl;
87
        QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
88 89 90
    }
}

91
void QueryOperation::showInformation(QList<Akabei::Package*> packages)
Lukas Appelhans's avatar
Lukas Appelhans committed
92 93 94 95 96
{
    if (packages.isEmpty())
        return;
    Akabei::Package * pkg = packages.first();
    QTextStream out(stdout);
Lukas Appelhans's avatar
Lukas Appelhans committed
97
    out.setFieldWidth(20);//TODO: Use QFontMetrics to get width of longest word and use that as width of the field (Also in -Si)
Lukas Appelhans's avatar
Lukas Appelhans committed
98 99 100 101 102 103
    out.setFieldAlignment(QTextStream::AlignLeft);
    out << i18n("Name") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->name() << endl;
    out << i18n("Version") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << QString(pkg->version().toByteArray().data()) << endl;
    out << i18n("URL") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->url().toString() << endl;
    out << i18n("Licenses") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->license() << endl;
    QStringList groups;
Lisa's avatar
Lisa committed
104 105
    foreach(Akabei::Group * g, pkg->groups())
    groups << g->name();
Lukas Appelhans's avatar
Lukas Appelhans committed
106 107 108 109 110 111 112 113 114 115 116 117 118 119
    out << i18n("Groups") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << groups.join(" ") << endl;
    out << i18n("Provides") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->provides().join(" ") << endl;
    out << i18n("Depends on") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->dependencies().join(" ") << endl;
    out << i18n("Optional dependencies") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->optionalDependencies().join(" ") << endl;
    //out << i18n("Required by:") << pkg->
    out << i18n("Replaces") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->replaces().join(" ") << endl;
    out << i18n("Installation size") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << KIO::convertSize(pkg->size()) << endl;
    out << i18n("Packager") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->packager() << endl;
    out << i18n("Architecture") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->arch() << endl;
    out << i18n("Creation time") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->buildDate().toString() << endl;
    out << i18n("Installation time") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->installDate().toString() << endl;
    out << i18n("Install reason") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << ((pkg->installReason() == Akabei::Package::InstalledAsDependencyReason) ? i18n("Installed as dependency") : i18n("Installed explicitely")) << endl;
    out << i18n("Installation script") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << (pkg->hasScriptlet() ? i18n("Yes") : i18n("No")) << endl;
    out << i18n("Description") << qSetFieldWidth(2) << ":" << qSetFieldWidth(20) << pkg->description() << endl;
Lukas Appelhans's avatar
Lukas Appelhans committed
120
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
121
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
122
}
Lukas Appelhans's avatar
Lukas Appelhans committed
123

Lisa's avatar
Lisa committed
124
void QueryOperation::showGroup(QUuid uuid, QList<Akabei::Group*> groups)
Lukas Appelhans's avatar
Lukas Appelhans committed
125 126
{
    Q_UNUSED(uuid)
Lukas Appelhans's avatar
Lukas Appelhans committed
127 128
    if (groups.isEmpty()) {
        QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
129
        return;
Lukas Appelhans's avatar
Lukas Appelhans committed
130
    }
Lukas Appelhans's avatar
Lukas Appelhans committed
131
    Akabei::Group * group = groups.first();
Lisa's avatar
Lisa committed
132

Lukas Appelhans's avatar
Lukas Appelhans committed
133 134
    QTextStream out(stdout);
    QMap<QString, Akabei::Package*> sorted;
Lisa's avatar
Lisa committed
135 136 137 138
    foreach(Akabei::Package * pkg, group->packages())
    sorted[pkg->name()] = pkg;
    foreach(Akabei::Package * pkg, sorted.values())
    out << group->name() << ' ' << pkg->name() << endl;
Lukas Appelhans's avatar
Lukas Appelhans committed
139
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
140
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
141
}
Lukas Appelhans's avatar
Lukas Appelhans committed
142

143
void QueryOperation::showChangelog(QList< Akabei::Package* > packages)
Lukas Appelhans's avatar
Lukas Appelhans committed
144
{
Lukas Appelhans's avatar
Lukas Appelhans committed
145 146
    if (packages.isEmpty()) {
        QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
147
        return;
Lukas Appelhans's avatar
Lukas Appelhans committed
148
    }
Lukas Appelhans's avatar
Lukas Appelhans committed
149 150 151 152
    Akabei::Package * pkg = packages.first();
    QTextStream out(stdout);
    out << pkg->retrieveChangelog() << endl;
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
153
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
154 155 156 157
}

void QueryOperation::showInstalledAsDeps(QList<Akabei::Package*> packages)
{
Lukas Appelhans's avatar
Lukas Appelhans committed
158 159
    if (packages.isEmpty()) {
        QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
160
        return;
Lukas Appelhans's avatar
Lukas Appelhans committed
161
    }
Lukas Appelhans's avatar
Lukas Appelhans committed
162
    QTextStream out(stdout);
163
    QMap<QString, Akabei::Package*> sorted;
Lisa's avatar
Lisa committed
164 165 166 167
    foreach(Akabei::Package * pkg, packages)
    sorted[pkg->name()] = pkg;
    foreach(Akabei::Package * pkg, sorted.values())
    out << pkg->name() << ' ' << pkg->version().toByteArray().data() << endl;
Lukas Appelhans's avatar
Lukas Appelhans committed
168
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
169
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
170 171
}

172
void QueryOperation::checkFiles(QList<Akabei::Package*> packages)
Lukas Appelhans's avatar
Lukas Appelhans committed
173
{
Lukas Appelhans's avatar
Lukas Appelhans committed
174 175
    if (packages.isEmpty()) {
        QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
176
        return;
Lukas Appelhans's avatar
Lukas Appelhans committed
177
    }
Lukas Appelhans's avatar
Lukas Appelhans committed
178 179 180 181
    Akabei::Package * pkg = packages.first();
    QTextStream out(stdout);
    int all = 0;
    int missing = 0;
Lisa's avatar
Lisa committed
182
    foreach(const QString & file, pkg->retrieveFiles()) {
Lukas Appelhans's avatar
Lukas Appelhans committed
183 184 185 186 187
        all++;
        if (!QFile::exists(Akabei::Config::instance()->rootDir().absoluteFilePath(file)))
            missing++;
    }
    out << pkg->name() << ": " << all << " overall files, " << missing << " file(s) missing" << endl;
Lukas Appelhans's avatar
Lukas Appelhans committed
188
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
189
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
190 191 192
}

void QueryOperation::showLocalPackages(const QString &query)
Lisa's avatar
Lisa committed
193
{
Lukas Appelhans's avatar
Lukas Appelhans committed
194 195 196 197 198 199
    QTextStream out(stdout);
    QList<Akabei::Package*> packages;
    if (!query.isEmpty())
        packages = Akabei::Backend::instance()->localDatabase()->searchPackages(query);
    else
        packages = Akabei::Backend::instance()->localDatabase()->packages();
Lisa's avatar
Lisa committed
200
    foreach(Akabei::Package * pkg, packages) {
Lukas Appelhans's avatar
Lukas Appelhans committed
201
        bool found = false;
Lisa's avatar
Lisa committed
202 203
        foreach(Akabei::Database * db, Akabei::Backend::instance()->databases()) {
            foreach(Akabei::Package * p, db->searchPackages(pkg->name())) {
Lukas Appelhans's avatar
Lukas Appelhans committed
204 205 206 207 208 209 210 211 212 213 214 215
                if (p->name() == pkg->name()) {
                    found = true;
                    break;
                }
            }
            if (found)
                break;
        }
        if (!found)
            out << pkg->name() << ' ' << pkg->version().toByteArray().data() << endl;
    }
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
216
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
217 218
}

Lukas Appelhans's avatar
Lukas Appelhans committed
219 220 221 222 223 224
void QueryOperation::showOwner(const QString &query)
{
    QTextStream out(stdout);
    if (!QFile::exists(query)) {
        out << "File does not exists: " << query << endl;
        out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
225
        QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
226 227
        return;
    }
Lisa's avatar
Lisa committed
228 229
    foreach(Akabei::Package * pkg, Akabei::Backend::instance()->localDatabase()->packages()) {
        foreach(const QString & file, pkg->retrieveFiles()) {
Lukas Appelhans's avatar
Lukas Appelhans committed
230 231 232
            if (Akabei::Config::instance()->rootDir().absoluteFilePath(file) == query) {
                out << query  << " is owned by " << pkg->name() << ' ' << pkg->version().toByteArray().data() << endl;
                out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
233
                QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
234 235 236 237 238 239
                return;
            }
        }
    }
    out << "Error: No packages owns " << query << endl;
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
240
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
241
}
Lukas Appelhans's avatar
Lukas Appelhans committed
242 243 244 245 246

void QueryOperation::showLocalQuery(QList<Akabei::Package*> packages)
{
    QTextStream out(stdout);
    QMap<QString, Akabei::Package*> sorted;
Lisa's avatar
Lisa committed
247 248 249
    foreach(Akabei::Package * pkg, packages)
    sorted[pkg->name()] = pkg;
    foreach(Akabei::Package * pkg, sorted.values()) {
Lukas Appelhans's avatar
Lukas Appelhans committed
250
        out << "local/" << pkg->name() << ' ' << pkg->version().toByteArray().data() << endl;
Lukas Appelhans's avatar
Lukas Appelhans committed
251
        out << "\t" << pkg->description() << endl;
Lukas Appelhans's avatar
Lukas Appelhans committed
252 253
    }
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
254
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
255
}
Lukas Appelhans's avatar
Lukas Appelhans committed
256 257 258 259 260 261

void QueryOperation::showNotRequired()
{
    QTextStream out(stdout);
    QList<Akabei::Package*> packages = Akabei::Backend::instance()->localDatabase()->packages();
    QMap<QString, Akabei::Package*> pkgs;
Lisa's avatar
Lisa committed
262 263 264 265 266
    foreach(Akabei::Package * pkg, packages)
    pkgs[pkg->name()] = pkg;
    foreach(Akabei::Package * pkg, packages) {
        foreach(const QString & dep, pkg->dependencies())
        pkgs.remove(dep);
Lukas Appelhans's avatar
Lukas Appelhans committed
267
    }
Lisa's avatar
Lisa committed
268 269
    foreach(Akabei::Package * pkg, pkgs.values())
    out << pkg->name() << ' ' << pkg->version().toByteArray().data() << endl;
Lukas Appelhans's avatar
Lukas Appelhans committed
270
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
271
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
272
}
Lukas Appelhans's avatar
Lukas Appelhans committed
273 274 275 276 277 278 279

void QueryOperation::showUpgradeable()
{
    //FIXME: Maybe don't even check for the highest version... redundant?
    QTextStream out(stdout);
    QList<Akabei::Package*> packages = Akabei::Backend::instance()->localDatabase()->packages();
    QMap<QString, Akabei::Package*> upgradeable;
Lisa's avatar
Lisa committed
280 281
    foreach(Akabei::Package * pkg, packages) {
        foreach(Akabei::Database * db, Akabei::Backend::instance()->databases()) {
Lukas Appelhans's avatar
Lukas Appelhans committed
282 283
            Akabei::Package::List list = db->queryPackages("SELECT * FROM packages WHERE Name LIKE \"" + pkg->name() + "\"");
            if (!list.isEmpty()) {
Lisa's avatar
Lisa committed
284
                foreach(Akabei::Package * p, list) {
Lukas Appelhans's avatar
Lukas Appelhans committed
285 286 287 288 289 290 291 292 293
                    if (p->version() > pkg->version() && p->name() == pkg->name()) {
                        if (upgradeable[p->name()] && upgradeable[p->name()]->version() > p->version())
                            continue;
                        upgradeable[p->name()] = p;
                    }
                }
            }
        }
    }
Lisa's avatar
Lisa committed
294 295 296

    foreach(Akabei::Package * pkg, upgradeable.values())
    out << pkg->name() << ' ' << pkg->version().toByteArray().data() << endl;
Lukas Appelhans's avatar
Lukas Appelhans committed
297
    out.flush();
Lukas Appelhans's avatar
Lukas Appelhans committed
298
    QCoreApplication::instance()->quit();
Lukas Appelhans's avatar
Lukas Appelhans committed
299
}