1 /*
2 * This file is part of TelepathyLoggerQt
3 *
4 * Copyright (C) 2011 Collabora Ltd. <http://www.collabora.co.uk/>
5 *
6 * This library is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "tpl-tool.h"
21 #include <tools/_gen/tpl-tool.moc.hpp>
22 #include <TelepathyLoggerQt/utils.h>
23 #include <QApplication>
24 #include <TelepathyQt/Account>
25 #include <TelepathyQt/AccountSet>
26 #include <TelepathyQt/AccountManager>
27 #include <TelepathyQt/ContactManager>
28 #include <TelepathyQt/Connection>
29 #include <TelepathyQt/PendingReady>
30 #include <TelepathyLoggerQt/Entity>
31 #include <TelepathyLoggerQt/Event>
32 #include <TelepathyLoggerQt/TextEvent>
33 #include <TelepathyLoggerQt/CallEvent>
34 #include <TelepathyLoggerQt/LogManager>
35 #include <TelepathyLoggerQt/PendingDates>
36 #include <TelepathyLoggerQt/PendingEntities>
37 #include <TelepathyLoggerQt/PendingEvents>
38 #include <TelepathyLoggerQt/PendingSearch>
39 #include <TelepathyLoggerQt/Init>
40 #include <glib-object.h>
41 #include <QGst/Init>
42 #include <QDebug>
43
44 #define TPL_TOOL_DATE_FORMAT "yyyyMMdd"
45
TplToolApplication(int & argc,char ** argv)46 TplToolApplication::TplToolApplication(int &argc, char **argv)
47 : QCoreApplication(argc, argv)
48 {
49 qDebug();
50
51 mAccountManager = Tp::AccountManager::create();
52 connect(mAccountManager->becomeReady(Tp::AccountManager::FeatureCore),
53 SIGNAL(finished(Tp::PendingOperation*)),
54 this,
55 SLOT(onAccountManagerReady(Tp::PendingOperation*)));
56 }
57
accountPtr(const QString & id)58 Tp::AccountPtr TplToolApplication::accountPtr(const QString &id)
59 {
60 qDebug();
61
62 mAccountPtr = Tpl::Utils::instance()->accountPtr(id);
63 if (!mAccountPtr->isValid()) {
64 return mAccountPtr;
65 }
66
67 connect(mAccountPtr->becomeReady(Tp::Features() << Tp::Account::FeatureCore << Tp::Account::FeatureAvatar),
68 SIGNAL(finished(Tp::PendingOperation*)),
69 this,
70 SLOT(onAccountReady(Tp::PendingOperation*)));
71
72 return mAccountPtr;
73 }
74
entityPtr(const QString & id)75 Tpl::EntityPtr TplToolApplication::entityPtr(const QString &id)
76 {
77 qDebug();
78
79 return Tpl::Entity::create(id.toUtf8(), Tpl::EntityTypeContact, NULL, NULL);
80 }
81
parseArgs1()82 bool TplToolApplication::parseArgs1()
83 {
84 qDebug();
85
86 QStringList args = arguments();
87
88 Tpl::LogManagerPtr logManager = Tpl::LogManager::instance();
89 if (logManager.isNull()) {
90 qWarning() << "LogManager not found";
91 return false;
92 }
93
94 if (args.size() == 2 && args.at(1) == "accounts") {
95 Tp::AccountSetPtr accountSet = Tpl::Utils::instance()->accountManagerPtr()->validAccounts();
96 QList<Tp::AccountPtr> accounts = accountSet->accounts();
97 Tp::AccountPtr account;
98 int i = 0;
99 Q_FOREACH(account, accounts) {
100 qDebug() << "account " << i++ << account->objectPath();
101 }
102 this->exit();
103 return true;
104 } else if ((args.size() == 3 && args.at(1) == "contacts") ||
105 (args.size() == 4 && args.at(1) == "exists") ||
106 (args.size() == 3 && args.at(1) == "entities") ||
107 (args.size() == 4 && args.at(1) == "dates") ||
108 (args.size() == 5 && args.at(1) == "events") ||
109 (args.size() == 5 && args.at(1) == "filteredEvents")) {
110 Tp::AccountPtr account = accountPtr(args.at(2));
111 if (account.isNull()) {
112 qWarning() << "Account not found " << args.at(2);
113 }
114 return true;
115 } else if (args.size() == 3 && args.at(1) == "search") {
116 Tpl::PendingSearch *ps = logManager->search(args.at(2), Tpl::EventTypeMaskAny);
117 qDebug() << "PendingSearch=" << ps;
118 if (!ps) {
119 qWarning() << "Error in search";
120 this->exit(-1);
121 return false;
122 }
123
124 connect(ps,
125 SIGNAL(finished(Tpl::PendingOperation*)),
126 this,
127 SLOT(onPendingSearch(Tpl::PendingOperation*)));
128
129 return true;
130 }
131
132 qDebug() << "Telepathy logger command line tool (qt4)";
133 qDebug() << "";
134 qDebug() << "General usage: tpl-tool <command> <parameters>";
135 qDebug() << "";
136 qDebug() << "tpl-tool accounts";
137 qDebug() << "tpl-tool contacts <account>";
138 qDebug() << "tpl-tool exists <account> <entity>";
139 qDebug() << "tpl-tool entities <account>";
140 qDebug() << "tpl-tool dates <account> <entity>";
141 qDebug() << "tpl-tool events <account> <entity> <date>";
142 qDebug() << "tpl-tool filteredEvents <account> <entity> <numEvents>";
143 qDebug() << "tpl-tool search <text>";
144 this->exit(-1);
145
146 return false;
147 }
148
parseArgs2()149 bool TplToolApplication::parseArgs2()
150 {
151 qDebug();
152
153 QStringList args = arguments();
154
155 Tpl::LogManagerPtr logManager = Tpl::LogManager::instance();
156 if (logManager.isNull()) {
157 qWarning() << "LogManager not found";
158 return false;
159 }
160
161 if (args.size() == 3 && args.at(1) == "contacts") {
162 Tp::Contacts contacts = mAccountPtr->connection()->contactManager()->allKnownContacts();
163 qDebug() << "number of contacts = " << contacts.size();
164
165 Tp::ContactPtr contact;
166 int i = 0;
167 Q_FOREACH(contact, contacts) {
168 qDebug() << "contact " << i++ << contact->id();
169 }
170 this->exit();
171 return true;
172 } else if (args.size() == 4 && args.at(1) == "exists") {
173 Tpl::EntityPtr entity = entityPtr(args.at(3));
174 if (entity.isNull()) {
175 qWarning() << "Entity not found " << args.at(3);
176 }
177
178 bool ret = logManager->exists(mAccountPtr, entity, Tpl::EventTypeMaskAny);
179 qDebug() << "tpl-tool exists " << args.at(2) << args.at(3) << " -> " << ret;
180 this->exit();
181 return true;
182 } else if (args.at(1) == "entities") {
183 Tpl::PendingEntities *pe = logManager->queryEntities(mAccountPtr);
184 qDebug() << "PendingEntities=" << pe;
185 if (!pe) {
186 qWarning() << "Error in PendingEntities";
187 this->exit(-1);
188 return false;
189 }
190
191 connect(pe,
192 SIGNAL(finished(Tpl::PendingOperation*)),
193 this,
194 SLOT(onPendingEntities(Tpl::PendingOperation*)));
195
196 return true;
197 } else if (args.at(1) == "dates") {
198 Tpl::EntityPtr entity = entityPtr(args.at(3));
199 if (entity.isNull()) {
200 qWarning() << "Entity not found " << args.at(3);
201 }
202
203 Tpl::PendingDates *pd = logManager->queryDates(mAccountPtr, entity, Tpl::EventTypeMaskAny);
204 qDebug() << "PendingDates=" << pd;
205 if (!pd) {
206 qWarning() << "Error in PendingDates";
207 this->exit(-1);
208 return false;
209 }
210
211 connect(pd,
212 SIGNAL(finished(Tpl::PendingOperation*)),
213 this,
214 SLOT(onPendingDates(Tpl::PendingOperation*)));
215
216 return true;
217 } else if (args.at(1) == "events") {
218 Tpl::EntityPtr entity = entityPtr(args.at(3));
219 if (entity.isNull()) {
220 qWarning() << "Entity not found " << args.at(3);
221 }
222
223 QDate date = QDate::fromString(args.at(4), TPL_TOOL_DATE_FORMAT);
224
225 Tpl::PendingEvents *pe = logManager->queryEvents(mAccountPtr, entity, Tpl::EventTypeMaskAny, date);
226 qDebug() << "PendingEvents=" << pe << "date=" << date;
227 if (!pe) {
228 qWarning() << "Error in PendingDates";
229 this->exit(-1);
230 return false;
231 }
232
233 connect(pe,
234 SIGNAL(finished(Tpl::PendingOperation*)),
235 this,
236 SLOT(onPendingEvents(Tpl::PendingOperation*)));
237
238 return true;
239 } else if (args.at(1) == "filteredEvents") {
240 Tpl::EntityPtr entity = entityPtr(args.at(3));
241 if (entity.isNull()) {
242 qWarning() << "Entity not found " << args.at(3);
243 }
244
245 Tpl::PendingEvents *pe = logManager->queryFilteredEvents(mAccountPtr, entity, Tpl::EventTypeMaskAny, args.at(4).toInt(), &TplToolApplication::eventFilterMethod, this);
246 qDebug() << "PendingEvents (filtered) =" << pe << "numEvents=" << args.at(4);
247 if (!pe) {
248 qWarning() << "Error in PendingDates";
249 this->exit(-1);
250 return false;
251 }
252
253 connect(pe,
254 SIGNAL(finished(Tpl::PendingOperation*)),
255 this,
256 SLOT(onPendingEvents(Tpl::PendingOperation*)));
257
258 return true;
259 }
260
261 this->exit(-1);
262 return false;
263 }
264
onAccountManagerReady(Tp::PendingOperation * po)265 void TplToolApplication::onAccountManagerReady(Tp::PendingOperation *po)
266 {
267 qDebug() << "po=" << po << "isError=" << po->isError();
268
269 if (po->isError()) {
270 qWarning() << "error getting account mananger ready";
271 exit(-1);
272 return;
273 }
274
275 Tpl::LogManagerPtr logManager = Tpl::LogManager::instance();
276 if (logManager.isNull()) {
277 qWarning() << "LogManager not found";
278 exit(-1);
279 return;
280 }
281
282 logManager->setAccountManagerPtr(mAccountManager);
283
284 parseArgs1();
285 }
286
onAccountReady(Tp::PendingOperation * po)287 void TplToolApplication::onAccountReady(Tp::PendingOperation *po)
288 {
289 qDebug() << "po=" << po << "isError=" << po->isError();
290
291 if (po->isError()) {
292 qWarning() << "error getting account ready";
293 exit(-1);
294 return;
295 }
296
297 Tp::ConnectionPtr connection = mAccountPtr->connection();
298 if (connection.isNull()) {
299 qWarning() << "error null connection";
300 exit(-1);
301 return;
302 }
303
304 connect(mAccountPtr->connection()->becomeReady(Tp::Features() << Tp::Connection::FeatureCore << Tp::Connection::FeatureSelfContact << Tp::Connection::FeatureRoster),
305 SIGNAL(finished(Tp::PendingOperation*)),
306 this,
307 SLOT(onConnectionReady(Tp::PendingOperation*)));
308 }
309
onConnectionReady(Tp::PendingOperation * po)310 void TplToolApplication::onConnectionReady(Tp::PendingOperation *po)
311 {
312 qDebug() << "po=" << po << "isError=" << po->isError();
313
314 if (po->isError()) {
315 qWarning() << "error getting connection ready";
316 exit(-1);
317 return;
318 }
319
320 parseArgs2();
321 }
322
onPendingSearch(Tpl::PendingOperation * po)323 void TplToolApplication::onPendingSearch(Tpl::PendingOperation *po)
324 {
325 Tpl::PendingSearch *ps = (Tpl::PendingSearch*) po;
326
327 if (ps->isError()) {
328 qWarning() << "error in search";
329 exit(-1);
330 return;
331 }
332
333 Tpl::SearchHitList hits = ps->hits();
334 qDebug() << " search hits " << hits.size();
335
336 int count = 0;
337
338 Q_FOREACH(const Tpl::SearchHit &hit, hits) {
339 qDebug() << count++ << "account=" << hit.account.data() << (hit.account.isNull() ? "null" : hit.account->objectPath())
340 << "date=" << hit.date.toString(TPL_TOOL_DATE_FORMAT)
341 << "target=" << (hit.target ? hit.target->identifier() + '/' + hit.target->alias() + '/' + QString::number(hit.target->entityType()) + '/' + hit.target->avatarToken() : "null");
342 }
343
344 this->exit();
345 }
346
onPendingEntities(Tpl::PendingOperation * po)347 void TplToolApplication::onPendingEntities(Tpl::PendingOperation *po)
348 {
349 Tpl::PendingEntities *pe = (Tpl::PendingEntities*) po;
350
351 if (pe->isError()) {
352 qWarning() << "error in search";
353 exit(-1);
354 return;
355 }
356
357 Tpl::EntityPtrList entities= pe->entities();
358 qDebug() << " Pending entities " << entities.size();
359
360 int count = 0;
361 Tpl::EntityPtr entity;
362 Q_FOREACH(entity, entities) {
363 qDebug() << count++ << "entity id=" << entity->identifier() << "alias=" << entity->alias() << "type=" << entity->entityType() << "avatarToken=" << entity->avatarToken();
364 }
365
366 this->exit();
367 }
368
onPendingDates(Tpl::PendingOperation * po)369 void TplToolApplication::onPendingDates(Tpl::PendingOperation *po)
370 {
371 Tpl::PendingDates *pd = (Tpl::PendingDates*) po;
372
373 if (pd->isError()) {
374 qWarning() << "error in search";
375 exit(-1);
376 return;
377 }
378
379 Tpl::QDateList dates = pd->dates();
380 qDebug() << " Pending dates " << dates.size();
381
382 int count = 0;
383 QDate date;
384 Q_FOREACH(date, dates) {
385 qDebug() << count++ << "date " << date.toString(TPL_TOOL_DATE_FORMAT);
386 }
387
388 this->exit();
389 }
390
onPendingEvents(Tpl::PendingOperation * po)391 void TplToolApplication::onPendingEvents(Tpl::PendingOperation *po)
392 {
393 Tpl::PendingEvents *pe = (Tpl::PendingEvents*) po;
394
395 if (pe->isError()) {
396 qWarning() << "error in PendingEvents";
397 exit(-1);
398 return;
399 }
400
401 Tpl::EventPtrList events = pe->events();
402 qDebug() << " Pending events " << events.size();
403
404 int count = 0;
405 QObject a;
406 Tpl::EventPtr event;
407 Q_FOREACH(event, events) {
408 Tpl::TextEventPtr textEvent = event.dynamicCast<Tpl::TextEvent>();
409 Tpl::CallEventPtr callEvent = event.dynamicCast<Tpl::CallEvent>();
410 if (!textEvent.isNull()) {
411 qDebug() << count++ << "textEvent"
412 << "timestamp=" << textEvent->timestamp().toString()
413 << "sender=" << textEvent->sender()->identifier()
414 << "receiver=" << textEvent->receiver()->identifier()
415 << "message=" << textEvent->message()
416 << "messageType=" << textEvent->messageType()
417 << "account=" << (textEvent->account() ? textEvent->account()->objectPath() : "null")
418 << "accountPath=" << textEvent->accountPath();
419 } else if (!callEvent.isNull()) {
420 qDebug() << count++ << "callEvent"
421 << "timestamp=" << callEvent->timestamp().toString()
422 << "sender=" << callEvent->sender()->identifier()
423 << "receiver=" << callEvent->receiver()->identifier()
424 << "duraton=" << callEvent->duration()
425 << "endActor=" << callEvent->endActor()->identifier()
426 << "endReason=" << callEvent->endReason()
427 << "detailedEndReason=" << callEvent->detailedEndReason()
428 << "account=" << (callEvent->account() ? callEvent->account()->objectPath() : "null")
429 << "accountPath=" << callEvent->accountPath();
430 } else {
431 qDebug() << count++ << "event"
432 << "timestamp=" << event->timestamp().toString()
433 << "sender=" << event->sender()->identifier()
434 << "receiver=" << event->receiver()->identifier()
435 << "account=" << (event->account() ? event->account()->objectPath() : "null")
436 << "accountPath=" << event->accountPath();
437 }
438 }
439
440 this->exit();
441 }
442
eventFilterMethod(const Tpl::EventPtr & event,void * user_data)443 bool TplToolApplication::eventFilterMethod(const Tpl::EventPtr &event, void *user_data)
444 {
445 return true;
446 }
447
main(int argc,char ** argv)448 int main(int argc, char **argv)
449 {
450 g_type_init();
451 Tp::registerTypes();
452
453 TplToolApplication app(argc, argv);
454 Tpl::init();
455
456 return app.exec();
457 }
458