You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
501 lines
10 KiB
501 lines
10 KiB
//=============================================================================
|
|
//
|
|
// Common interface for BitTorrent clients.
|
|
//
|
|
// File : torr_ktorrentdcopinterface.cpp
|
|
// Creation date : Fri Jan 1 15:42:25 2007 GMT by Alexander Stillich
|
|
//
|
|
// This file is part of the KVirc irc client distribution
|
|
// Copyright (C) 2001-2005 Szymon Stefanek (pragma at kvirc dot net)
|
|
// Copyright (C) 2007 Alexander Stillich (torque at pltn dot org)
|
|
//
|
|
// This program is FREE software. You can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 2
|
|
// of the License, or (at your opinion) any later version.
|
|
//
|
|
// This program is distributed in the HOPE that it will be USEFUL,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
// See the GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, write to the Free Software Foundation,
|
|
// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
//
|
|
//=============================================================================
|
|
|
|
#ifdef COMPILE_TDE_SUPPORT
|
|
|
|
#include "kvi_app.h"
|
|
|
|
|
|
#include "dcopclient.h" // <-- this include should be hidden in kvilib
|
|
|
|
#include "tc_ktorrentdcopinterface.h"
|
|
|
|
|
|
#include "kvi_locale.h"
|
|
#include <tqtimer.h>
|
|
|
|
TORR_IMPLEMENT_DESCRIPTOR(
|
|
KviKTorrentDCOPInterface,
|
|
"ktorrentdcop",
|
|
__tr2qs_ctx(
|
|
"An interface to TDE's excellent KTorrent client.\n" \
|
|
"Download it from http://www.ktorrent.org\n",
|
|
"torrent"
|
|
)
|
|
)
|
|
|
|
#define ERROR_MSG \
|
|
TQCString msg; \
|
|
if (!findRunningApp(m_szAppId)) \
|
|
msg = "KTorrent's isn't running!"; \
|
|
else \
|
|
msg = "Something's wrong here! KTorrent's DCOP interface has probably changed."; \
|
|
m_lastError = __tr2qs_ctx(TQString(msg), "torrent"); \
|
|
tqDebug("%s (%s:%d): %s", __PRETTY_FUNCTION__, __FILE__, __LINE__, (const char*)msg); \
|
|
|
|
#define ERROR_MSG_RANGE(I, SIZE) \
|
|
KviTQString::sprintf(m_lastError, __tr2qs_ctx("Index out of range: %d [0-%d]!", "torrent"), I, (SIZE>0)?(SIZE-1):0); \
|
|
tqDebug("%s (%s:%d): Index out of range: %d [0-%d]!", __PRETTY_FUNCTION__ , __FILE__, __LINE__, I, (SIZE>0)?(SIZE-1):0);
|
|
|
|
#define ERROR_RET_BOOL \
|
|
{ \
|
|
ERROR_MSG \
|
|
return false; \
|
|
}
|
|
|
|
#define ERROR_RET_NUM \
|
|
{ \
|
|
ERROR_MSG \
|
|
return -1; \
|
|
}
|
|
|
|
// TODO: unused?
|
|
#define ERROR_RET_STRING \
|
|
{ \
|
|
ERROR_MSG \
|
|
return ""; \
|
|
}
|
|
|
|
#define ERROR_RET_VOID \
|
|
{ \
|
|
ERROR_MSG \
|
|
return; \
|
|
}
|
|
|
|
#define CHECK_RANGE_BOOL(I, SIZE) \
|
|
if (I<0 || I>=SIZE) \
|
|
{ \
|
|
ERROR_MSG_RANGE(I, SIZE) \
|
|
return false; \
|
|
}
|
|
|
|
#define CHECK_RANGE_INT(I, SIZE) \
|
|
if (I<0 || I>=SIZE) \
|
|
{ \
|
|
ERROR_MSG_RANGE(I, SIZE) \
|
|
return -1; \
|
|
}
|
|
|
|
#define CHECK_RANGE_STRING(I, SIZE) \
|
|
if (I<0 || I>=SIZE) \
|
|
{ \
|
|
ERROR_MSG_RANGE(I, SIZE) \
|
|
return ""; \
|
|
}
|
|
|
|
KviKTorrentDCOPInterface::KviKTorrentDCOPInterface()
|
|
: KviDCOPHelper(false, "ktorrent")
|
|
{
|
|
printf("KviKTorrentDCOPInterface\n");
|
|
|
|
TQTimer *timer = new TQTimer(this);
|
|
connect(timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(slotTimer()));
|
|
timer->start(250, FALSE);
|
|
|
|
// make sure we have a list of files,
|
|
// otherwise functions dealing would
|
|
// fail if called the first time
|
|
slotTimer();
|
|
}
|
|
|
|
KviKTorrentDCOPInterface::~KviKTorrentDCOPInterface()
|
|
{
|
|
printf("~KviKTorrentDCOPInterface\n");
|
|
}
|
|
|
|
void KviKTorrentDCOPInterface::slotTimer()
|
|
{
|
|
if (!findRunningApp(m_szAppId))
|
|
return;
|
|
|
|
m_ti.clear();
|
|
|
|
KviValueList<int> ret;
|
|
if (!qvalueListIntRetIntDCOPCall("KTorrent", "getTorrentNumbers(int)", ret, 0))
|
|
ERROR_RET_VOID
|
|
|
|
for (int i=0; i<ret.size(); i++)
|
|
{
|
|
KviQCStringList info;
|
|
if (!qcstringListRetIntDCOPCall("KTorrent", "getTorrentInfo(int)", info, ret[i]))
|
|
ERROR_RET_VOID
|
|
|
|
if (info.size() == 0)
|
|
continue;
|
|
|
|
TorrentInfo item;
|
|
if (!makeTorrentInfo(item, info))
|
|
return;
|
|
|
|
item.num = ret[i];
|
|
m_ti.append(item);
|
|
}
|
|
|
|
qHeapSort(m_ti);
|
|
}
|
|
|
|
int KviKTorrentDCOPInterface::detect()
|
|
{
|
|
if (!findRunningApp(m_szAppId))
|
|
return 0;
|
|
|
|
return 100;
|
|
}
|
|
|
|
bool makeSize(float &sz, const TQString &s, const TQString &u)
|
|
{
|
|
bool ok;
|
|
sz = s.toFloat(&ok);
|
|
if (!ok)
|
|
return false;
|
|
|
|
if (u == "B")
|
|
;
|
|
else
|
|
if (u == "KB")
|
|
sz = sz * 1024.0;
|
|
else
|
|
if (u == "MB")
|
|
sz = sz * 1024.0 * 1024.0;
|
|
else
|
|
if (u == "GB")
|
|
sz = sz * 1024.0 * 1024.0 * 1024.0;
|
|
else
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool KviKTorrentDCOPInterface::start(int i)
|
|
{
|
|
CHECK_RANGE_BOOL(i, m_ti.size())
|
|
|
|
tqDebug("starting %s [%d]", (const char*)m_ti[i].name, m_ti[i].num);
|
|
if (!voidRetIntDCOPCall("KTorrent", "start(int)", m_ti[i].num))
|
|
ERROR_RET_BOOL
|
|
|
|
return true;
|
|
}
|
|
|
|
bool KviKTorrentDCOPInterface::stop(int i)
|
|
{
|
|
CHECK_RANGE_BOOL(i, m_ti.size())
|
|
|
|
tqDebug("stopping %s [%d]", (const char*)m_ti[i].name, m_ti[i].num);
|
|
if (!voidRetIntBoolDCOPCall("KTorrent", "stop(int, bool)", m_ti[i].num, true))
|
|
ERROR_RET_BOOL
|
|
|
|
return true;
|
|
}
|
|
|
|
bool KviKTorrentDCOPInterface::announce(int i)
|
|
{
|
|
CHECK_RANGE_BOOL(i, m_ti.size())
|
|
|
|
tqDebug("announcing %s [%d]", (const char*)m_ti[i].name, m_ti[i].num);
|
|
if (!voidRetIntDCOPCall("KTorrent", "announce(int)", m_ti[i].num))
|
|
ERROR_RET_BOOL
|
|
return true;
|
|
}
|
|
|
|
TQString KviKTorrentDCOPInterface::state(int i)
|
|
{
|
|
CHECK_RANGE_STRING(i, m_ti.size())
|
|
|
|
return m_ti[i].state;
|
|
}
|
|
|
|
TQString KviKTorrentDCOPInterface::name(int i)
|
|
{
|
|
CHECK_RANGE_STRING(i, m_ti.size())
|
|
|
|
return m_ti[i].name;
|
|
}
|
|
|
|
int KviKTorrentDCOPInterface::fileCount(int i)
|
|
{
|
|
CHECK_RANGE_INT(i, m_ti.size())
|
|
|
|
int ret;
|
|
if (!intRetIntDCOPCall("KTorrent", "getFileCount(int)", ret, m_ti[i].num))
|
|
ERROR_RET_NUM
|
|
|
|
return ret;
|
|
}
|
|
|
|
TQString KviKTorrentDCOPInterface::fileName(int i, int file)
|
|
{
|
|
CHECK_RANGE_STRING(i, m_ti.size())
|
|
|
|
QCStringList ret;
|
|
if (!qcstringListRetIntDCOPCall("KTorrent", "getFileNames(int)", ret, m_ti[i].num))
|
|
ERROR_RET_STRING
|
|
|
|
CHECK_RANGE_STRING(file, ret.size())
|
|
|
|
return ret[file];
|
|
}
|
|
|
|
TQString KviKTorrentDCOPInterface::filePriority(int i, int file)
|
|
{
|
|
CHECK_RANGE_STRING(i, m_ti.size())
|
|
|
|
TQValueList<int> ret;
|
|
if (!qvalueListIntRetIntDCOPCall("KTorrent", "getFilePriorities(int)",ret, m_ti[i].num))
|
|
ERROR_RET_STRING
|
|
|
|
CHECK_RANGE_STRING(file, ret.size())
|
|
|
|
tqDebug("prio: %d", ret[file]);
|
|
switch (ret[file])
|
|
{
|
|
case 1: return "low";
|
|
case 2: return "normal";
|
|
case 3: return "high";
|
|
}
|
|
|
|
ERROR_RET_STRING
|
|
}
|
|
|
|
bool KviKTorrentDCOPInterface::setFilePriority(int i, int file, const TQString &prio)
|
|
{
|
|
CHECK_RANGE_BOOL(i, m_ti.size())
|
|
|
|
int prion;
|
|
if (prio == "low")
|
|
prion = 1;
|
|
else
|
|
if (prio == "normal")
|
|
prion = 2;
|
|
else
|
|
if (prio == "high")
|
|
prion = 1;
|
|
else
|
|
ERROR_RET_BOOL
|
|
|
|
if (!voidRetIntIntIntDCOPCall("KTorrent", "setFilePriority(int,int,int)", m_ti[i].num, file, prion))
|
|
ERROR_RET_BOOL
|
|
|
|
return true;
|
|
}
|
|
|
|
bool KviKTorrentDCOPInterface::startAll()
|
|
{
|
|
if (!voidRetIntDCOPCall("KTorrent", "startAll(int)", 3))
|
|
ERROR_RET_BOOL
|
|
|
|
return true;
|
|
}
|
|
|
|
bool KviKTorrentDCOPInterface::stopAll()
|
|
{
|
|
if (!voidRetIntDCOPCall("KTorrent", "stopAll(int)", 3))
|
|
ERROR_RET_BOOL
|
|
|
|
return true;
|
|
}
|
|
|
|
int KviKTorrentDCOPInterface::count()
|
|
{
|
|
return m_ti.size();
|
|
}
|
|
|
|
float KviKTorrentDCOPInterface::speedUp()
|
|
{
|
|
KviQCStringList ret;
|
|
if (!qcstringListRetVoidDCOPCall("KTorrent", "getInfo()", ret))
|
|
ERROR_RET_NUM
|
|
|
|
TQStringList tmp = TQStringList::split(" ", ret[2]);
|
|
if (tmp.size() != 8)
|
|
ERROR_RET_NUM
|
|
|
|
bool ok;
|
|
float f = tmp[6].toFloat(&ok);
|
|
if (!ok)
|
|
ERROR_RET_NUM
|
|
|
|
return f;
|
|
}
|
|
|
|
float KviKTorrentDCOPInterface::speedDown()
|
|
{
|
|
KviQCStringList ret;
|
|
if (!qcstringListRetVoidDCOPCall("KTorrent", "getInfo()", ret))
|
|
ERROR_RET_NUM
|
|
|
|
TQStringList tmp = TQStringList::split(" ", ret[2]);
|
|
if (tmp.size() != 8)
|
|
ERROR_RET_NUM
|
|
|
|
bool ok;
|
|
float f = tmp[2].toFloat(&ok);
|
|
if (!ok)
|
|
ERROR_RET_NUM
|
|
|
|
return f;
|
|
}
|
|
|
|
float KviKTorrentDCOPInterface::trafficUp()
|
|
{
|
|
KviQCStringList ret;
|
|
if (!qcstringListRetVoidDCOPCall("KTorrent", "getInfo()", ret))
|
|
ERROR_RET_NUM
|
|
|
|
TQStringList tmp = TQStringList::split(" ", ret[1]);
|
|
if (tmp.size() != 8)
|
|
ERROR_RET_NUM
|
|
|
|
float f;
|
|
if (!makeSize(f, tmp[6], tmp[7]))
|
|
ERROR_RET_NUM
|
|
|
|
return f;
|
|
}
|
|
|
|
float KviKTorrentDCOPInterface::trafficDown()
|
|
{
|
|
KviQCStringList ret;
|
|
if (!qcstringListRetVoidDCOPCall("KTorrent", "getInfo()", ret))
|
|
ERROR_RET_NUM
|
|
|
|
TQStringList tmp = TQStringList::split(" ", ret[1]);
|
|
if (tmp.size() != 8)
|
|
ERROR_RET_NUM
|
|
|
|
float f;
|
|
if (!makeSize(f, tmp[2], tmp[3]))
|
|
ERROR_RET_NUM
|
|
|
|
return f;
|
|
}
|
|
|
|
bool KviKTorrentDCOPInterface::makeTorrentInfo(TorrentInfo &ti, const KviQCStringList &ret)
|
|
{
|
|
if (ret.size() != 10)
|
|
ERROR_RET_BOOL
|
|
|
|
ti.name = ret[0];
|
|
if (ret[1] == "Seeding")
|
|
ti.state = "Seeding";
|
|
else
|
|
if (ret[1] == "Stalled")
|
|
ti.state = "Stalled";
|
|
else
|
|
if (ret[1] == "Downloading")
|
|
ti.state = "Downloading";
|
|
else
|
|
ti.state = "Stopped";
|
|
|
|
|
|
TQStringList tmp;
|
|
tmp = TQStringList::split(" ", ret[2]);
|
|
if (tmp.size()!=2 || !makeSize(ti.trafficDown, tmp[0], tmp[1]))
|
|
ERROR_RET_BOOL
|
|
|
|
tmp = TQStringList::split(" ", ret[3]);
|
|
if (tmp.size()!=2 || !makeSize(ti.size, tmp[0], tmp[1]))
|
|
ERROR_RET_BOOL
|
|
|
|
tmp = TQStringList::split(" ", ret[4]);
|
|
if (tmp.size()!=2 || !makeSize(ti.trafficUp, tmp[0], tmp[1]))
|
|
ERROR_RET_BOOL
|
|
|
|
|
|
bool ok;
|
|
tmp = TQStringList::split(" ", ret[5]);
|
|
if (tmp.size()!=2)
|
|
ERROR_RET_BOOL
|
|
ti.speedDown = tmp[0].toFloat(&ok);
|
|
if (!ok)
|
|
ERROR_RET_BOOL
|
|
|
|
tmp = TQStringList::split(" ", ret[6]);
|
|
if (tmp.size()!=2)
|
|
ERROR_RET_BOOL
|
|
ti.speedUp = tmp[0].toFloat(&ok);
|
|
if (!ok)
|
|
ERROR_RET_BOOL
|
|
|
|
|
|
// torrent name, status, downloaded, size, uploaded, down spd, up spd, none, peers, % complete
|
|
ti.peers = ret[8].toInt(&ok);
|
|
if (!ok)
|
|
ERROR_RET_BOOL
|
|
|
|
tmp = TQStringList::split(" ", ret[9]);
|
|
if (tmp.size()!=2)
|
|
ERROR_RET_BOOL
|
|
ti.percent = tmp[0].toFloat(&ok);
|
|
if (!ok)
|
|
ERROR_RET_BOOL
|
|
|
|
return true;
|
|
}
|
|
|
|
int KviKTorrentDCOPInterface::maxUploadSpeed()
|
|
{
|
|
int ret;
|
|
if (!intRetVoidDCOPCall("KTorrent", "maxUploadRate()", ret))
|
|
{
|
|
ERROR_MSG
|
|
return -1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int KviKTorrentDCOPInterface::maxDownloadSpeed()
|
|
{
|
|
int ret;
|
|
if (!intRetVoidDCOPCall("KTorrent", "maxDownloadRate()", ret))
|
|
{
|
|
ERROR_MSG
|
|
return -1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool KviKTorrentDCOPInterface::setMaxUploadSpeed(int kbytes_per_sec)
|
|
{
|
|
if (!voidRetIntDCOPCall("KTorrent", "setMaxUploadSpeed(int)", kbytes_per_sec))
|
|
ERROR_RET_BOOL
|
|
return true;
|
|
}
|
|
|
|
bool KviKTorrentDCOPInterface::setMaxDownloadSpeed(int kbytes_per_sec)
|
|
{
|
|
if (!voidRetIntDCOPCall("KTorrent", "setMaxDownloadSpeed(int)", kbytes_per_sec))
|
|
ERROR_RET_BOOL
|
|
return true;
|
|
}
|
|
|
|
|
|
#include "tc_ktorrentdcopinterface.moc"
|
|
|
|
#endif // COMPILE_TDE_SUPPORT
|
|
|