File indexing completed on 2024-05-12 05:12:40

0001 /*
0002  * Copyright (C) 2014  Bhaskar Kandiyal <bkandiyal@gmail.com>
0003  *
0004  * This program is free software; you can redistribute it and/or modify
0005  * it under the terms of the GNU General Public License as published by
0006  * the Free Software Foundation; either version 2 of the License, or
0007  * (at your option) any later version.
0008  *
0009  * This program is distributed in the hope that it will be useful,
0010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  * GNU General Public License for more details.
0013  *
0014  * You should have received a copy of the GNU General Public License along
0015  * with this program; if not, write to the Free Software Foundation, Inc.,
0016  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
0017  *
0018  */
0019 
0020 #include "agentscommand.h"
0021 
0022 #include <klocalizedstring.h>
0023 
0024 #include <Akonadi/AgentManager>
0025 #include <Akonadi/AgentInstance>
0026 
0027 #include <qstringlist.h>
0028 #include <QVector>
0029 
0030 #include <iostream>
0031 #include <iomanip>
0032 
0033 #include "commandfactory.h"
0034 
0035 using namespace Akonadi;
0036 
0037 DEFINE_COMMAND("agents", AgentsCommand, I18N_NOOP("Manage Akonadi agents"));
0038 
0039 AgentsCommand::AgentsCommand(QObject *parent)
0040     : AbstractCommand(parent),
0041       mStateArg(ONLINE),
0042       mOption(LIST)
0043 {
0044 }
0045 
0046 void AgentsCommand::setupCommandOptions(QCommandLineParser *parser)
0047 {
0048     addOptionsOption(parser);
0049     parser->addOption(QCommandLineOption((QStringList() << "l" << "list"), i18n("List all agents")));
0050     parser->addOption(QCommandLineOption((QStringList() << "s" << "setstate"), i18n("Set state \"online\" or \"offline\" for specified agents"), i18nc("@info:shell", "state")));
0051     parser->addOption(QCommandLineOption((QStringList() << "g" << "getstate"), i18n("Get state for the specified agent")));
0052     parser->addOption(QCommandLineOption((QStringList() << "i" << "info"), i18n("Show information about the specified agent")));
0053     parser->addOption(QCommandLineOption((QStringList() << "r" << "restart"), i18n("Restart the specified agent")));
0054     addDryRunOption(parser);
0055 
0056     parser->addPositionalArgument("agents", i18nc("@info:shell", "Agents to operate on"), i18nc("@info:shell", "[agents...]"));
0057 }
0058 
0059 int AgentsCommand::initCommand(QCommandLineParser *parser)
0060 {
0061     mArguments = parser->positionalArguments();
0062 
0063     if (!getCommonOptions(parser)) return InvalidUsage;
0064 
0065     if (parser->isSet("list")) {
0066         mOption = LIST;
0067     } else {
0068         if (!checkArgCount(mArguments, 1, i18nc("@info:shell", "No agents or options specified"))) return InvalidUsage;
0069 
0070         if (parser->isSet("info")) {
0071             mOption = INFO;
0072         } else if (parser->isSet("restart")) {
0073             mOption = RESTART;
0074         } else if (parser->isSet("getstate")) {
0075             mOption = GETSTATE;
0076         } else if (parser->isSet("setstate")) {
0077             mOption = SETSTATE;
0078             const QString state = parser->value("setstate");
0079 
0080             if (state.length()>=2 && state.compare(QStringLiteral("online").left(state.length())) == 0) {
0081                 mStateArg = ONLINE;
0082             } else if (state.length()>=2 && state.compare(QStringLiteral("offline").left(state.length())) == 0) {
0083                 mStateArg = OFFLINE;
0084             } else {
0085                 emitErrorSeeHelp(i18nc("@info:shell", "Invalid state '%1'", state));
0086                 return InvalidUsage;
0087             }
0088         } else {
0089             emitErrorSeeHelp(i18nc("@info:shell", "No option specified"));
0090             return InvalidUsage;
0091         }
0092     }
0093 
0094     return NoError;
0095 }
0096 
0097 static bool instanceLessThan(const AgentInstance &a, const AgentInstance &b)
0098 {
0099     return (a.identifier() < b.identifier());
0100 }
0101 
0102 void AgentsCommand::start()
0103 {
0104     switch (mOption) {
0105     case LIST: {
0106         QVector<AgentInstance> instances = AgentManager::self()->instances();
0107         std::sort(instances.begin(), instances.end(), &instanceLessThan);
0108         printAgentStatus(instances);
0109         break;
0110     }
0111     case SETSTATE: {
0112         setState();
0113         break;
0114     }
0115     case GETSTATE: {
0116         getState();
0117         break;
0118     }
0119     case INFO: {
0120         showInfo();
0121         break;
0122     }
0123 
0124     case RESTART: {
0125         restartAgents();
0126         break;
0127     }
0128 
0129     default: {
0130         emitErrorSeeHelp(i18nc("@info:shell", "Invalid parameters"));
0131         emit finished(InvalidUsage);
0132         break;
0133     }
0134     }
0135 
0136     emit finished(NoError);
0137 }
0138 
0139 void AgentsCommand::printAgentStatus(const QVector<AgentInstance> &agents)
0140 {
0141     int max_width = 0;
0142     for (int i = 0; i < agents.length(); i++) {
0143         AgentInstance agent = agents.at(i);
0144         if (max_width < agent.identifier().length()) {
0145             max_width = agent.identifier().length();
0146         }
0147     }
0148 
0149     std::cout << "Name" << std::setw(max_width + 20) << "Status" << std::endl;
0150     for (int i = 0; i < agents.length(); i++) {
0151         AgentInstance agent = agents.at(i);
0152         int width = max_width - agent.identifier().length();
0153         std::cout << agent.identifier().toLocal8Bit().data() << std::setw(width + 18) << " ";
0154         std::cout << agent.statusMessage().toLocal8Bit().data() << std::endl;
0155     }
0156 }
0157 
0158 void AgentsCommand::setState()
0159 {
0160     AgentManager *manager = AgentManager::self();
0161     QList<AgentInstance> agentList;
0162 
0163     for (int i = 0; i < mArguments.length(); i++) {
0164         AgentInstance instance = manager->instance(mArguments.at(i));
0165         if (!instance.isValid()) {
0166             emit error(i18nc("@info:shell", "No agent exists with the identifier '%1'", mArguments.at(i)));
0167             emit finished(RuntimeError);
0168             return;
0169         }
0170         agentList.append(instance);
0171     }
0172 
0173     if (!isDryRun()) {
0174         for (int i = 0; i < agentList.length(); i++) {
0175             AgentInstance instance = agentList.at(i);
0176             switch (mStateArg) {
0177             case ONLINE: {
0178                 instance.setIsOnline(true);
0179                 break;
0180             }
0181             case OFFLINE: {
0182                 instance.setIsOnline(false);
0183                 break;
0184             }
0185             }
0186         }
0187     }
0188 }
0189 
0190 void AgentsCommand::getState()
0191 {
0192     AgentManager *manager = AgentManager::self();
0193     QVector<AgentInstance> agentList;
0194 
0195     for (int i = 0; i < mArguments.length(); i++) {
0196         AgentInstance instance = manager->instance(mArguments.at(i));
0197         if (!instance.isValid()) {
0198             emit error(i18nc("@info:shell", "No agent exists with the identifier '%1'", mArguments.at(i)));
0199             emit finished(RuntimeError);
0200             return;
0201         }
0202         agentList.append(instance);
0203     }
0204 
0205     printAgentStatus(agentList);
0206 }
0207 
0208 void AgentsCommand::showInfo()
0209 {
0210     AgentManager *manager = AgentManager::self();
0211     QList<AgentInstance> agentList;
0212 
0213     for (int i = 0; i < mArguments.length(); i++) {
0214         AgentInstance instance = manager->instance(mArguments.at(i));
0215         if (!instance.isValid()) {
0216             emit error(i18nc("@info:shell", "No agent exists with the identifier '%1'", mArguments.at(i)));
0217             emit finished(RuntimeError);
0218             return;
0219         }
0220         agentList.append(instance);
0221     }
0222 
0223     for (int i = 0; i < agentList.length(); i++) {
0224         AgentInstance instance = agentList.at(i);
0225         std::cout << qPrintable(i18nc("@info:shell", "ID:      ")) << qPrintable(instance.identifier()) << std::endl;
0226         std::cout << qPrintable(i18nc("@info:shell", "Name:    ")) << qPrintable(instance.name()) << std::endl;
0227         std::cout << qPrintable(i18nc("@info:shell", "Status:  ")) << qPrintable(instance.statusMessage()) << std::endl;
0228         if ((i + 1) < mArguments.length()) {
0229             std::cout << std::endl;
0230         }
0231     }
0232 }
0233 
0234 void AgentsCommand::restartAgents()
0235 {
0236     AgentManager *manager = AgentManager::self();
0237     QList<AgentInstance> agentList;
0238 
0239     for (int i = 0; i < mArguments.length(); i++) {
0240         AgentInstance instance = manager->instance(mArguments.at(i));
0241         if (!instance.isValid()) {
0242             emit error(i18nc("@info:shell", "No agent exists with the identifier '%1'", mArguments.at(i)));
0243             emit finished(RuntimeError);
0244             return;
0245         }
0246         agentList.append(instance);
0247     }
0248 
0249     if (!isDryRun()) {
0250         for (int i = 0; i < agentList.length(); i++) {
0251             AgentInstance instance = agentList.at(i);
0252             instance.restart();
0253         }
0254     }
0255 }