Akonadi Contacts

qskypedialer.cpp
1 /*
2  This file is part of Akonadi Contact.
3 
4  SPDX-FileCopyrightText: 2009 Tobias Koenig <[email protected]>
5 
6  SPDX-License-Identifier: LGPL-2.0-or-later
7 */
8 
9 #include "qskypedialer.h"
10 
11 #include <KLocalizedString>
12 #include <QDBusConnection>
13 #include <QDBusConnectionInterface>
14 #include <QDBusInterface>
15 #include <QDBusReply>
16 #include <QProcess>
17 
18 #if !defined(Q_OS_WIN)
19 #include <unistd.h>
20 #else
21 #include <windows.h>
22 #endif
23 
24 static bool isSkypeServiceRegistered()
25 {
26  const QString service(QStringLiteral("com.Skype.API"));
27 
29  if (interface->isServiceRegistered(service)) {
30  return true;
31  }
32 
33  interface = QDBusConnection::sessionBus().interface();
34  if (interface->isServiceRegistered(service)) {
35  return true;
36  }
37 
38  return false;
39 }
40 
41 static QDBusInterface *searchSkypeDBusInterface()
42 {
43  const QString service(QStringLiteral("com.Skype.API"));
44  const QString path(QStringLiteral("/com/Skype"));
45 
46  auto interface = new QDBusInterface(service, path, QString(), QDBusConnection::sessionBus());
47  if (!interface->isValid()) {
48  delete interface;
49  interface = new QDBusInterface(service, path, QString(), QDBusConnection::sessionBus());
50  }
51 
52  return interface;
53 }
54 
55 QSkypeDialer::QSkypeDialer(const QString &applicationName)
56  : QDialer(applicationName)
57 {
58 }
59 
60 QSkypeDialer::~QSkypeDialer()
61 {
62  delete mInterface;
63 }
64 
65 bool QSkypeDialer::initializeSkype()
66 {
67  if (mInterface && mInterface->isValid()) {
68  return true;
69  }
70 
71  // first check whether dbus interface is available yet
72  if (!isSkypeServiceRegistered()) {
73  // it could be skype is not running yet, so start it now
74  if (!QProcess::startDetached(QStringLiteral("skype"), QStringList())) {
75  mErrorMessage = i18n("Unable to start skype process, check that skype executable is in your PATH variable.");
76  return false;
77  }
78 
79  const int runs = 100;
80  for (int i = 0; i < runs; ++i) {
81  if (!isSkypeServiceRegistered()) {
82 #if !defined(Q_OS_WIN)
83  ::sleep(2);
84 #else
85  Sleep(2000);
86 #endif
87  } else {
88  break;
89  }
90  }
91  }
92 
93  // check again for the dbus interface
94  mInterface = searchSkypeDBusInterface();
95 
96  if (!mInterface->isValid()) {
97  delete mInterface;
98  mInterface = nullptr;
99 
100  mErrorMessage = i18n("Skype Public API (D-Bus) seems to be disabled.");
101  return false;
102  }
103 
104  QDBusReply<QString> reply = mInterface->call(QStringLiteral("Invoke"), QStringLiteral("NAME %1").arg(mApplicationName));
105  if (reply.value() != QLatin1String("OK")) {
106  delete mInterface;
107  mInterface = nullptr;
108 
109  mErrorMessage = i18n("Skype registration failed.");
110  return false;
111  }
112 
113  reply = mInterface->call(QStringLiteral("Invoke"), QStringLiteral("PROTOCOL 1"));
114  if (reply.value() != QLatin1String("PROTOCOL 1")) {
115  delete mInterface;
116  mInterface = nullptr;
117 
118  mErrorMessage = i18n("Protocol mismatch.");
119  return false;
120  }
121 
122  return true;
123 }
124 
125 bool QSkypeDialer::dialNumber(const QString &number)
126 {
127  if (!initializeSkype()) {
128  return false;
129  }
130 
131  QDBusReply<QString> reply = mInterface->call(QStringLiteral("Invoke"), QStringLiteral("CALL %1").arg(number));
132 
133  return true;
134 }
135 
136 bool QSkypeDialer::sendSms(const QString &number, const QString &text)
137 {
138  if (!initializeSkype()) {
139  return false;
140  }
141 
142  // First we create a new SMS object that gets an ID. We need that ID later...
143  QDBusReply<QString> reply = mInterface->call(QStringLiteral("Invoke"), QStringLiteral("CREATE SMS OUTGOING %1").arg(number));
144  const QString messageId = reply.value().section(QLatin1Char(' '), 1, 1);
145 
146  // Set the SMS text
147  reply = mInterface->call(QStringLiteral("Invoke"), QStringLiteral("SET SMS %1 BODY %2").arg(messageId, text));
148 
149  // Send the SMS
150  reply = mInterface->call(QStringLiteral("Invoke"), QStringLiteral("ALTER SMS %1 SEND").arg(messageId));
151  if (reply.value().contains(QLatin1String("ERROR"))) {
152  mErrorMessage = reply.value();
153  // As sending the message failed (not enough Skype credit), lets delete the message
154  reply = mInterface->call(QStringLiteral("Invoke"), QStringLiteral("DELETE SMS %1").arg(messageId));
155  return false;
156  }
157 
158  return true;
159 }
QDBusConnectionInterface * interface() const const
bool startDetached(qint64 *pid)
QDBusConnection sessionBus()
QDBusReply< bool > isServiceRegistered(const QString &serviceName) const const
QDBusReply::Type value() const const
QString i18n(const char *text, const TYPE &arg...)
if(recurs()&&!first)
bool isValid(QStringView ifopt)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Wed Jun 23 2021 23:09:25 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.