|
|
|
#include <noatun/downloader.h>
|
|
|
|
#include <noatun/app.h>
|
|
|
|
#include <assert.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
#include <kio/job.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
|
|
|
|
DownloadItem::DownloadItem()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
DownloadItem::~DownloadItem()
|
|
|
|
{
|
|
|
|
dequeue();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DownloadItem::isDownloaded() const
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString DownloadItem::localFilename() const
|
|
|
|
{
|
|
|
|
return mLocalFilename;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DownloadItem::setLocalFilename(const TQString &filename)
|
|
|
|
{
|
|
|
|
mLocalFilename=filename;
|
|
|
|
}
|
|
|
|
|
|
|
|
void DownloadItem::downloadFinished()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void DownloadItem::downloaded(int )
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void DownloadItem::downloadTimeout()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
bool DownloadItem::enqueue(const KURL &url)
|
|
|
|
{
|
|
|
|
if (url.isLocalFile())
|
|
|
|
{
|
|
|
|
setLocalFilename(url.path());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
napp->downloader()->enqueue(this, url);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void DownloadItem::dequeue()
|
|
|
|
{
|
|
|
|
napp->downloader()->dequeue(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Downloader::Downloader(TQObject *parent)
|
|
|
|
: TQObject(parent), localfile(0), current(0), mJob(0), mTimeout(0)
|
|
|
|
{
|
|
|
|
mStarted=false;
|
|
|
|
mUnstartedQueue=new TQPtrList<Downloader::QueueItem>;
|
|
|
|
}
|
|
|
|
|
|
|
|
Downloader::~Downloader()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Downloader::start()
|
|
|
|
{
|
|
|
|
assert(!mStarted);
|
|
|
|
mStarted=true;
|
|
|
|
if (current)
|
|
|
|
emit enqueued(current->notifier, current->file);
|
|
|
|
|
|
|
|
for (TQPtrListIterator<Downloader::QueueItem> i(*mUnstartedQueue); i.current(); ++i)
|
|
|
|
{
|
|
|
|
(*i)->notifier->mLocalFilename = (*i)->local;
|
|
|
|
mQueue.append(*i);
|
|
|
|
emit enqueued((*i)->notifier, (*i)->file);
|
|
|
|
}
|
|
|
|
|
|
|
|
delete mUnstartedQueue;
|
|
|
|
mUnstartedQueue=0;
|
|
|
|
TQTimer::singleShot(0, this, TQT_SLOT(getNext()));
|
|
|
|
}
|
|
|
|
|
|
|
|
static TQString nonExistantFile(const TQString &file)
|
|
|
|
{
|
|
|
|
if (file.right(1)=="/") return i18n("Unknown");
|
|
|
|
int i=0;
|
|
|
|
TQString f(file);
|
|
|
|
while (TQFile(f).exists())
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
f=file;
|
|
|
|
f.insert(f.findRev('.'), '_'+TQString::number(i));
|
|
|
|
}
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Downloader::enqueue(DownloadItem *notifier, const KURL &file)
|
|
|
|
{
|
|
|
|
if (file.isLocalFile()) return 0;
|
|
|
|
QueueItem *i=new QueueItem;
|
|
|
|
i->notifier=notifier;
|
|
|
|
i->file=file;
|
|
|
|
|
|
|
|
if (!mStarted)
|
|
|
|
{
|
|
|
|
i->local=notifier->mLocalFilename;
|
|
|
|
if (!notifier->localFilename().length())
|
|
|
|
{
|
|
|
|
i->local =
|
|
|
|
nonExistantFile(napp->saveDirectory()+'/'+file.fileName());
|
|
|
|
}
|
|
|
|
mUnstartedQueue->append(i);
|
|
|
|
return i->local;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!notifier->localFilename().length())
|
|
|
|
{
|
|
|
|
notifier->mLocalFilename=
|
|
|
|
i->local =
|
|
|
|
nonExistantFile(napp->saveDirectory()+'/'+file.fileName());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
i->local = notifier->mLocalFilename;
|
|
|
|
}
|
|
|
|
|
|
|
|
mQueue.append(i);
|
|
|
|
TQTimer::singleShot(0, this, TQT_SLOT(getNext()));
|
|
|
|
emit enqueued(notifier, file);
|
|
|
|
return i->local;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Downloader::dequeue(DownloadItem *notifier)
|
|
|
|
{
|
|
|
|
if (current && notifier==current->notifier)
|
|
|
|
{
|
|
|
|
mJob->kill();
|
|
|
|
jobDone(mJob);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
for (TQPtrListIterator<Downloader::QueueItem> i(mQueue); i.current(); ++i)
|
|
|
|
{
|
|
|
|
if ((*i)->notifier==notifier)
|
|
|
|
{
|
|
|
|
mQueue.removeRef(*i);
|
|
|
|
if (mStarted)
|
|
|
|
emit dequeued(notifier);
|
|
|
|
delete *i;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Downloader::getNext()
|
|
|
|
{
|
|
|
|
if (current) return;
|
|
|
|
if (!mStarted) return;
|
|
|
|
if (mQueue.isEmpty()) return;
|
|
|
|
current=mQueue.take(0);
|
|
|
|
|
|
|
|
// open the TQFile
|
|
|
|
localfile=new TQFile(current->local);
|
|
|
|
localfile->open(IO_ReadWrite | IO_Append);
|
|
|
|
|
|
|
|
mJob= KIO::get(current->file, true, false);
|
|
|
|
connect(mJob, TQT_SIGNAL(data(KIO::Job*, const TQByteArray&)), TQT_SLOT(data(KIO::Job*, const TQByteArray&)));
|
|
|
|
connect(mJob, TQT_SIGNAL(result(KIO::Job*)), TQT_SLOT(jobDone(KIO::Job*)));
|
|
|
|
connect(mJob, TQT_SIGNAL(percent(KIO::Job*, unsigned long)), TQT_SLOT(percent(KIO::Job*, unsigned long)));
|
|
|
|
|
|
|
|
if (mTimeout)
|
|
|
|
delete mTimeout;
|
|
|
|
mTimeout=new TQTimer(this);
|
|
|
|
mTimeout->start(30000, true);
|
|
|
|
connect(mTimeout, TQT_SIGNAL(timeout()), TQT_SLOT(giveUpWithThisDownloadServerIsRunningNT()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Downloader::data(KIO::Job *, const TQByteArray &data)
|
|
|
|
{
|
|
|
|
localfile->writeBlock(data);
|
|
|
|
localfile->flush();
|
|
|
|
delete mTimeout;
|
|
|
|
mTimeout=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Downloader::jobDone(KIO::Job *)
|
|
|
|
{
|
|
|
|
delete mTimeout;
|
|
|
|
mTimeout=0;
|
|
|
|
current->notifier->downloadFinished();
|
|
|
|
if (mStarted)
|
|
|
|
emit dequeued(current->notifier);
|
|
|
|
delete current;
|
|
|
|
current=0;
|
|
|
|
mJob=0;
|
|
|
|
getNext();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Downloader::giveUpWithThisDownloadServerIsRunningNT()
|
|
|
|
{
|
|
|
|
delete mTimeout;
|
|
|
|
mTimeout=0;
|
|
|
|
if (!current) return;
|
|
|
|
DownloadItem *old=current->notifier;
|
|
|
|
if (!old) return;
|
|
|
|
old->downloadTimeout();
|
|
|
|
current=0;
|
|
|
|
mJob=0;
|
|
|
|
delete old;
|
|
|
|
getNext();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Downloader::percent( KIO::Job *, unsigned long percent)
|
|
|
|
{
|
|
|
|
if (current && current->notifier)
|
|
|
|
current->notifier->downloaded((int)percent);
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "downloader.moc"
|
|
|
|
|