File indexing completed on 2024-04-28 12:45:43

0001 /*
0002  * This file is part of TelepathyLoggerQt
0003  *
0004  * Copyright (C) 2011 Collabora Ltd. <http://www.collabora.co.uk/>
0005  *
0006  * This library is free software; you can redistribute it and/or modify
0007  * it under the terms of the GNU Lesser General Public License as published
0008  * by the Free Software Foundation; either version 2.1 of the License, or
0009  * (at your option) any later version.
0010  *
0011  * This program is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014  * GNU General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU Lesser General Public License
0017  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0018  */
0019 
0020 #include "tpl-tool.h"
0021 #include <tools/_gen/tpl-tool.moc.hpp>
0022 #include <TelepathyLoggerQt/utils.h>
0023 #include <QApplication>
0024 #include <TelepathyQt/Account>
0025 #include <TelepathyQt/AccountSet>
0026 #include <TelepathyQt/AccountManager>
0027 #include <TelepathyQt/ContactManager>
0028 #include <TelepathyQt/Connection>
0029 #include <TelepathyQt/PendingReady>
0030 #include <TelepathyLoggerQt/Entity>
0031 #include <TelepathyLoggerQt/Event>
0032 #include <TelepathyLoggerQt/TextEvent>
0033 #include <TelepathyLoggerQt/CallEvent>
0034 #include <TelepathyLoggerQt/LogManager>
0035 #include <TelepathyLoggerQt/PendingDates>
0036 #include <TelepathyLoggerQt/PendingEntities>
0037 #include <TelepathyLoggerQt/PendingEvents>
0038 #include <TelepathyLoggerQt/PendingSearch>
0039 #include <TelepathyLoggerQt/Init>
0040 #include <glib-object.h>
0041 #include <QGst/Init>
0042 #include <QDebug>
0043 
0044 #define TPL_TOOL_DATE_FORMAT "yyyyMMdd"
0045 
0046 TplToolApplication::TplToolApplication(int &argc, char **argv)
0047     : QCoreApplication(argc, argv)
0048 {
0049     qDebug();
0050 
0051     mAccountManager = Tp::AccountManager::create();
0052     connect(mAccountManager->becomeReady(Tp::AccountManager::FeatureCore),
0053             SIGNAL(finished(Tp::PendingOperation*)),
0054             this,
0055             SLOT(onAccountManagerReady(Tp::PendingOperation*)));
0056 }
0057 
0058 Tp::AccountPtr TplToolApplication::accountPtr(const QString &id)
0059 {
0060     qDebug();
0061 
0062     mAccountPtr = Tpl::Utils::instance()->accountPtr(id);
0063     if (!mAccountPtr->isValid()) {
0064         return mAccountPtr;
0065     }
0066 
0067     connect(mAccountPtr->becomeReady(Tp::Features() << Tp::Account::FeatureCore << Tp::Account::FeatureAvatar),
0068             SIGNAL(finished(Tp::PendingOperation*)),
0069             this,
0070             SLOT(onAccountReady(Tp::PendingOperation*)));
0071 
0072     return mAccountPtr;
0073 }
0074 
0075 Tpl::EntityPtr TplToolApplication::entityPtr(const QString &id)
0076 {
0077     qDebug();
0078 
0079     return Tpl::Entity::create(id.toUtf8(), Tpl::EntityTypeContact, NULL, NULL);
0080 }
0081 
0082 bool TplToolApplication::parseArgs1()
0083 {
0084     qDebug();
0085 
0086     QStringList args = arguments();
0087 
0088     Tpl::LogManagerPtr logManager = Tpl::LogManager::instance();
0089     if (logManager.isNull()) {
0090         qWarning() << "LogManager not found";
0091         return false;
0092     }
0093 
0094     if (args.size() == 2 && args.at(1) == "accounts") {
0095         Tp::AccountSetPtr accountSet = Tpl::Utils::instance()->accountManagerPtr()->validAccounts();
0096         QList<Tp::AccountPtr> accounts = accountSet->accounts();
0097         Tp::AccountPtr account;
0098         int i = 0;
0099         Q_FOREACH(account, accounts) {
0100             qDebug() << "account " << i++ << account->objectPath();
0101         }
0102         this->exit();
0103         return true;
0104     } else if ((args.size() == 3 && args.at(1) == "contacts") ||
0105                (args.size() == 4 && args.at(1) == "exists") ||
0106                (args.size() == 3 && args.at(1) == "entities") ||
0107                (args.size() == 4 && args.at(1) == "dates") ||
0108                (args.size() == 5 && args.at(1) == "events") ||
0109                (args.size() == 5 && args.at(1) == "filteredEvents")) {
0110         Tp::AccountPtr account = accountPtr(args.at(2));
0111         if (account.isNull()) {
0112             qWarning() << "Account not found " << args.at(2);
0113         }
0114         return true;
0115     } else if (args.size() == 3 && args.at(1) == "search") {
0116         Tpl::PendingSearch *ps = logManager->search(args.at(2), Tpl::EventTypeMaskAny);
0117         qDebug() << "PendingSearch=" << ps;
0118         if (!ps) {
0119             qWarning() << "Error in search";
0120             this->exit(-1);
0121             return false;
0122         }
0123 
0124         connect(ps,
0125                 SIGNAL(finished(Tpl::PendingOperation*)),
0126                 this,
0127                 SLOT(onPendingSearch(Tpl::PendingOperation*)));
0128 
0129         return true;
0130     }
0131 
0132     qDebug() << "Telepathy logger command line tool (qt4)";
0133     qDebug() << "";
0134     qDebug() << "General usage: tpl-tool <command> <parameters>";
0135     qDebug() << "";
0136     qDebug() << "tpl-tool accounts";
0137     qDebug() << "tpl-tool contacts <account>";
0138     qDebug() << "tpl-tool exists <account> <entity>";
0139     qDebug() << "tpl-tool entities <account>";
0140     qDebug() << "tpl-tool dates <account> <entity>";
0141     qDebug() << "tpl-tool events <account> <entity> <date>";
0142     qDebug() << "tpl-tool filteredEvents <account> <entity> <numEvents>";
0143     qDebug() << "tpl-tool search <text>";
0144     this->exit(-1);
0145 
0146     return false;
0147 }
0148 
0149 bool TplToolApplication::parseArgs2()
0150 {
0151     qDebug();
0152 
0153     QStringList args = arguments();
0154 
0155     Tpl::LogManagerPtr logManager = Tpl::LogManager::instance();
0156     if (logManager.isNull()) {
0157         qWarning() << "LogManager not found";
0158         return false;
0159     }
0160 
0161     if (args.size() == 3 && args.at(1) == "contacts") {
0162         Tp::Contacts contacts = mAccountPtr->connection()->contactManager()->allKnownContacts();
0163         qDebug() << "number of contacts = " << contacts.size();
0164 
0165         Tp::ContactPtr contact;
0166         int i = 0;
0167         Q_FOREACH(contact, contacts) {
0168             qDebug() << "contact " << i++ << contact->id();
0169         }
0170         this->exit();
0171         return true;
0172     } else if (args.size() == 4 && args.at(1) == "exists") {
0173         Tpl::EntityPtr entity = entityPtr(args.at(3));
0174         if (entity.isNull()) {
0175             qWarning() << "Entity not found " << args.at(3);
0176         }
0177 
0178         bool ret = logManager->exists(mAccountPtr, entity, Tpl::EventTypeMaskAny);
0179         qDebug() << "tpl-tool exists " << args.at(2) << args.at(3) << " -> " << ret;
0180         this->exit();
0181         return true;
0182     } else if (args.at(1) == "entities") {
0183         Tpl::PendingEntities *pe = logManager->queryEntities(mAccountPtr);
0184         qDebug() << "PendingEntities=" << pe;
0185         if (!pe) {
0186             qWarning() << "Error in PendingEntities";
0187             this->exit(-1);
0188             return false;
0189         }
0190 
0191         connect(pe,
0192                 SIGNAL(finished(Tpl::PendingOperation*)),
0193                 this,
0194                 SLOT(onPendingEntities(Tpl::PendingOperation*)));
0195 
0196         return true;
0197     } else if (args.at(1) == "dates") {
0198         Tpl::EntityPtr entity = entityPtr(args.at(3));
0199         if (entity.isNull()) {
0200             qWarning() << "Entity not found " << args.at(3);
0201         }
0202 
0203         Tpl::PendingDates *pd = logManager->queryDates(mAccountPtr, entity, Tpl::EventTypeMaskAny);
0204         qDebug() << "PendingDates=" << pd;
0205         if (!pd) {
0206             qWarning() << "Error in PendingDates";
0207             this->exit(-1);
0208             return false;
0209         }
0210 
0211         connect(pd,
0212                 SIGNAL(finished(Tpl::PendingOperation*)),
0213                 this,
0214                 SLOT(onPendingDates(Tpl::PendingOperation*)));
0215 
0216         return true;
0217     } else if (args.at(1) == "events") {
0218         Tpl::EntityPtr entity = entityPtr(args.at(3));
0219         if (entity.isNull()) {
0220             qWarning() << "Entity not found " << args.at(3);
0221         }
0222 
0223         QDate date = QDate::fromString(args.at(4), TPL_TOOL_DATE_FORMAT);
0224 
0225         Tpl::PendingEvents *pe = logManager->queryEvents(mAccountPtr, entity, Tpl::EventTypeMaskAny, date);
0226         qDebug() << "PendingEvents=" << pe << "date=" << date;
0227         if (!pe) {
0228             qWarning() << "Error in PendingDates";
0229             this->exit(-1);
0230             return false;
0231         }
0232 
0233         connect(pe,
0234                 SIGNAL(finished(Tpl::PendingOperation*)),
0235                 this,
0236                 SLOT(onPendingEvents(Tpl::PendingOperation*)));
0237 
0238         return true;
0239     } else if (args.at(1) == "filteredEvents") {
0240         Tpl::EntityPtr entity = entityPtr(args.at(3));
0241         if (entity.isNull()) {
0242             qWarning() << "Entity not found " << args.at(3);
0243         }
0244 
0245         Tpl::PendingEvents *pe = logManager->queryFilteredEvents(mAccountPtr, entity, Tpl::EventTypeMaskAny, args.at(4).toInt(), &TplToolApplication::eventFilterMethod, this);
0246         qDebug() << "PendingEvents (filtered) =" << pe << "numEvents=" << args.at(4);
0247         if (!pe) {
0248             qWarning() << "Error in PendingDates";
0249             this->exit(-1);
0250             return false;
0251         }
0252 
0253         connect(pe,
0254                 SIGNAL(finished(Tpl::PendingOperation*)),
0255                 this,
0256                 SLOT(onPendingEvents(Tpl::PendingOperation*)));
0257 
0258         return true;
0259     }
0260 
0261     this->exit(-1);
0262     return false;
0263 }
0264 
0265 void TplToolApplication::onAccountManagerReady(Tp::PendingOperation *po)
0266 {
0267     qDebug() << "po=" << po << "isError=" << po->isError();
0268 
0269     if (po->isError()) {
0270         qWarning() << "error getting account mananger ready";
0271         exit(-1);
0272         return;
0273     }
0274 
0275     Tpl::LogManagerPtr logManager = Tpl::LogManager::instance();
0276     if (logManager.isNull()) {
0277         qWarning() << "LogManager not found";
0278         exit(-1);
0279         return;
0280     }
0281 
0282     logManager->setAccountManagerPtr(mAccountManager);
0283 
0284     parseArgs1();
0285 }
0286 
0287 void TplToolApplication::onAccountReady(Tp::PendingOperation *po)
0288 {
0289     qDebug() << "po=" << po << "isError=" << po->isError();
0290 
0291     if (po->isError()) {
0292         qWarning() << "error getting account ready";
0293         exit(-1);
0294         return;
0295     }
0296 
0297     Tp::ConnectionPtr connection = mAccountPtr->connection();
0298     if (connection.isNull()) {
0299         qWarning() << "error null connection";
0300         exit(-1);
0301         return;
0302     }
0303 
0304     connect(mAccountPtr->connection()->becomeReady(Tp::Features() << Tp::Connection::FeatureCore << Tp::Connection::FeatureSelfContact << Tp::Connection::FeatureRoster),
0305         SIGNAL(finished(Tp::PendingOperation*)),
0306         this,
0307         SLOT(onConnectionReady(Tp::PendingOperation*)));
0308 }
0309 
0310 void TplToolApplication::onConnectionReady(Tp::PendingOperation *po)
0311 {
0312     qDebug() << "po=" << po << "isError=" << po->isError();
0313 
0314     if (po->isError()) {
0315         qWarning() << "error getting connection ready";
0316         exit(-1);
0317         return;
0318     }
0319 
0320     parseArgs2();
0321 }
0322 
0323 void TplToolApplication::onPendingSearch(Tpl::PendingOperation *po)
0324 {
0325     Tpl::PendingSearch *ps = (Tpl::PendingSearch*) po;
0326 
0327     if (ps->isError()) {
0328         qWarning() << "error in search";
0329         exit(-1);
0330         return;
0331     }
0332 
0333     Tpl::SearchHitList hits = ps->hits();
0334     qDebug() << " search hits " << hits.size();
0335 
0336     int count = 0;
0337 
0338     Q_FOREACH(const Tpl::SearchHit &hit, hits) {
0339         qDebug() << count++ << "account=" << hit.account.data() << (hit.account.isNull() ? "null" : hit.account->objectPath())
0340                  << "date=" << hit.date.toString(TPL_TOOL_DATE_FORMAT)
0341                  << "target=" << (hit.target ? hit.target->identifier() + '/' + hit.target->alias() + '/' + QString::number(hit.target->entityType()) + '/' + hit.target->avatarToken() : "null");
0342     }
0343 
0344     this->exit();
0345 }
0346 
0347 void TplToolApplication::onPendingEntities(Tpl::PendingOperation *po)
0348 {
0349     Tpl::PendingEntities *pe = (Tpl::PendingEntities*) po;
0350 
0351     if (pe->isError()) {
0352         qWarning() << "error in search";
0353         exit(-1);
0354         return;
0355     }
0356 
0357     Tpl::EntityPtrList entities= pe->entities();
0358     qDebug() << " Pending entities " << entities.size();
0359 
0360     int count = 0;
0361     Tpl::EntityPtr entity;
0362     Q_FOREACH(entity, entities) {
0363         qDebug() << count++ << "entity id=" << entity->identifier() << "alias=" << entity->alias() << "type=" << entity->entityType() << "avatarToken=" << entity->avatarToken();
0364     }
0365 
0366     this->exit();
0367 }
0368 
0369 void TplToolApplication::onPendingDates(Tpl::PendingOperation *po)
0370 {
0371     Tpl::PendingDates *pd = (Tpl::PendingDates*) po;
0372 
0373     if (pd->isError()) {
0374         qWarning() << "error in search";
0375         exit(-1);
0376         return;
0377     }
0378 
0379     Tpl::QDateList dates = pd->dates();
0380     qDebug() << " Pending dates " << dates.size();
0381 
0382     int count = 0;
0383     QDate date;
0384     Q_FOREACH(date, dates) {
0385         qDebug() << count++ << "date " << date.toString(TPL_TOOL_DATE_FORMAT);
0386     }
0387 
0388     this->exit();
0389 }
0390 
0391 void TplToolApplication::onPendingEvents(Tpl::PendingOperation *po)
0392 {
0393     Tpl::PendingEvents *pe = (Tpl::PendingEvents*) po;
0394 
0395     if (pe->isError()) {
0396         qWarning() << "error in PendingEvents";
0397         exit(-1);
0398         return;
0399     }
0400 
0401     Tpl::EventPtrList events = pe->events();
0402     qDebug() << " Pending events " << events.size();
0403 
0404     int count = 0;
0405     QObject a;
0406     Tpl::EventPtr event;
0407     Q_FOREACH(event, events) {
0408         Tpl::TextEventPtr textEvent = event.dynamicCast<Tpl::TextEvent>();
0409         Tpl::CallEventPtr callEvent = event.dynamicCast<Tpl::CallEvent>();
0410         if (!textEvent.isNull()) {
0411             qDebug() << count++ << "textEvent"
0412                       << "timestamp=" << textEvent->timestamp().toString()
0413                       << "sender=" << textEvent->sender()->identifier()
0414                       << "receiver=" << textEvent->receiver()->identifier()
0415                       << "message=" << textEvent->message()
0416                       << "messageType=" << textEvent->messageType()
0417                       << "account=" << (textEvent->account() ? textEvent->account()->objectPath() : "null")
0418                       << "accountPath=" << textEvent->accountPath();
0419         } else if (!callEvent.isNull()) {
0420             qDebug() << count++ << "callEvent"
0421                       << "timestamp=" << callEvent->timestamp().toString()
0422                       << "sender=" << callEvent->sender()->identifier()
0423                       << "receiver=" << callEvent->receiver()->identifier()
0424                       << "duraton=" << callEvent->duration()
0425                       << "endActor=" << callEvent->endActor()->identifier()
0426                       << "endReason=" << callEvent->endReason()
0427                       << "detailedEndReason=" << callEvent->detailedEndReason()
0428                       << "account=" << (callEvent->account() ? callEvent->account()->objectPath() : "null")
0429                       << "accountPath=" << callEvent->accountPath();
0430         } else {
0431             qDebug() << count++ << "event"
0432                       << "timestamp=" << event->timestamp().toString()
0433                       << "sender=" << event->sender()->identifier()
0434                       << "receiver=" << event->receiver()->identifier()
0435                       << "account=" << (event->account() ? event->account()->objectPath() : "null")
0436                       << "accountPath=" << event->accountPath();
0437         }
0438     }
0439 
0440     this->exit();
0441 }
0442 
0443 bool TplToolApplication::eventFilterMethod(const Tpl::EventPtr &event, void *user_data)
0444 {
0445     return true;
0446 }
0447 
0448 int main(int argc, char **argv)
0449 {
0450     g_type_init();
0451     Tp::registerTypes();
0452 
0453     TplToolApplication app(argc, argv);
0454     Tpl::init();
0455 
0456     return app.exec();
0457 }