File indexing completed on 2024-04-28 15:29:25
0001 /* 0002 Duplicates Example 0003 SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> 0004 0005 SPDX-License-Identifier: LGPL-2.1-or-later 0006 */ 0007 0008 #include <QCommandLineParser> 0009 #include <QCoreApplication> 0010 #include <QTimer> 0011 0012 #include <duplicatesfinder_p.h> 0013 #include <matchessolver_p.h> 0014 #include <personsmodel.h> 0015 0016 #include <cstdio> 0017 #include <iostream> 0018 0019 using namespace KPeople; 0020 0021 class ResultPrinter : public QObject 0022 { 0023 Q_OBJECT 0024 public Q_SLOTS: 0025 void print(KJob *j) 0026 { 0027 QList<Match> res = ((DuplicatesFinder *)j)->results(); 0028 std::cout << "Results: " << res.count() << std::endl; 0029 for (QList<Match>::iterator it = res.begin(); it != res.end();) { 0030 QStringList roles = it->matchReasons(); 0031 QStringList rA; 0032 QStringList rB; 0033 0034 AbstractContact::Ptr aA = it->indexA.data(PersonsModel::PersonVCardRole).value<AbstractContact::Ptr>(); 0035 AbstractContact::Ptr aB = it->indexB.data(PersonsModel::PersonVCardRole).value<AbstractContact::Ptr>(); 0036 0037 Q_ASSERT(!it->reasons.isEmpty()); 0038 for (Match::MatchReason i : std::as_const(it->reasons)) { 0039 rA += it->matchValue(i, aA); 0040 rB += it->matchValue(i, aB); 0041 } 0042 std::cout << "\t- " << qPrintable(roles.join(QStringLiteral(", "))) << ": " << it->indexA.row() << " " << it->indexB.row() 0043 << " because: " << qPrintable(rA.join(QStringLiteral(", "))) << " // " << qPrintable(rB.join(QStringLiteral(", "))) << '.' << std::endl; 0044 bool remove = false; 0045 if (m_action == Ask) { 0046 for (char ans = ' '; ans != 'y' && ans != 'n';) { 0047 std::cout << "apply? (y/n) "; 0048 std::cin >> ans; 0049 remove = ans == 'n'; 0050 } 0051 } 0052 if (remove) { 0053 it = res.erase(it); 0054 } else { 0055 ++it; 0056 } 0057 } 0058 0059 if ((m_action == Apply || m_action == Ask) && !res.isEmpty()) { 0060 MatchesSolver *s = new MatchesSolver(res, m_model, this); 0061 connect(s, SIGNAL(finished(KJob *)), this, SLOT(matchesSolverDone(KJob *))); 0062 s->start(); 0063 } else { 0064 QCoreApplication::instance()->quit(); 0065 } 0066 } 0067 0068 void matchesSolverDone(KJob *job) 0069 { 0070 if (job->error() == 0) { 0071 std::cout << "Matching successfully finished" << std::endl; 0072 } else { 0073 std::cout << "Matching failed with error: " << job->error() << std::endl; 0074 } 0075 QCoreApplication::instance()->quit(); 0076 } 0077 0078 public: 0079 enum MatchAction { 0080 Apply, 0081 NotApply, 0082 Ask, 0083 }; 0084 MatchAction m_action; 0085 PersonsModel *m_model; 0086 }; 0087 0088 int main(int argc, char **argv) 0089 { 0090 QCoreApplication app(argc, argv); 0091 PersonsModel model; 0092 0093 ResultPrinter r; 0094 r.m_model = &model; 0095 { 0096 QCommandLineParser parser; 0097 parser.addOption(QCommandLineOption(QStringLiteral("ask"), QStringLiteral("Ask whether to actually do the merge"))); 0098 parser.addOption(QCommandLineOption(QStringLiteral("apply"), QStringLiteral("Actually apply all merges. (!!!)"))); 0099 parser.addHelpOption(); 0100 parser.process(app); 0101 r.m_action = parser.isSet(QStringLiteral("apply")) ? ResultPrinter::Apply 0102 : parser.isSet(QStringLiteral("ask")) ? ResultPrinter::Ask 0103 : ResultPrinter::NotApply; 0104 } 0105 0106 DuplicatesFinder *f = new DuplicatesFinder(&model); 0107 QObject::connect(f, SIGNAL(finished(KJob *)), &r, SLOT(print(KJob *))); 0108 0109 QTimer *t = new QTimer(&app); 0110 t->setInterval(500); 0111 t->setSingleShot(true); 0112 QObject::connect(&model, SIGNAL(modelInitialized(bool)), t, SLOT(start())); 0113 QObject::connect(&model, SIGNAL(rowsInserted(QModelIndex, int, int)), t, SLOT(start())); 0114 QObject::connect(t, SIGNAL(timeout()), f, SLOT(start())); 0115 0116 app.exec(); 0117 } 0118 0119 #include "duplicates.moc"