|
|
/*------------------------------------------------------------------------------
|
|
|
-- This file is a part of the QLop Software
|
|
|
-- Copyright (C) 2015, Plasma Physics Laboratory - CNRS
|
|
|
--
|
|
|
-- 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 option) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
-------------------------------------------------------------------------------*/
|
|
|
/*-- Author : Alexis Jeandet
|
|
|
-- Mail : alexis.jeandet@member.fsf.org
|
|
|
----------------------------------------------------------------------------*/
|
|
|
|
|
|
#include "filedownloader.h"
|
|
|
#include <QFile>
|
|
|
#include <QIcon>
|
|
|
#include <qlopsettings.h>
|
|
|
#include <QHostInfo>
|
|
|
|
|
|
FileDownloader* FileDownloader::_self=NULL;
|
|
|
QNetworkAccessManager* FileDownloader::m_WebCtrl=NULL;
|
|
|
QList<FileDownloaderTask*>* FileDownloader::m_pendingTasks=NULL;
|
|
|
QDockWidget* FileDownloader::m_gui=NULL;
|
|
|
DownLoadHistory* FileDownloader::m_DownLoadHistory=NULL;
|
|
|
FileDowloaderSettingsGUI* FileDownloader::m_SettingsGui=NULL;
|
|
|
QLopNetworkProxyFactory* FileDownloader::m_ProxyFactory=NULL;
|
|
|
|
|
|
#define _INIT if(Q_UNLIKELY(_self==NULL)){ init();}
|
|
|
|
|
|
|
|
|
|
|
|
int FileDownloader::downloadFile(QUrl fileUrl, const QString &name)
|
|
|
{
|
|
|
_INIT
|
|
|
if(QFile::exists(name)|| QFile::exists(name+".part"))
|
|
|
{
|
|
|
return -1;
|
|
|
}
|
|
|
int ID=_self->getTaskId();
|
|
|
if(ID!=-1)
|
|
|
{
|
|
|
QNetworkRequest request(fileUrl);
|
|
|
QNetworkReply* reply = m_WebCtrl->head(request);
|
|
|
if(reply && (reply->error()==QNetworkReply::NoError))
|
|
|
{
|
|
|
FileDownloaderTask*task=new FileDownloaderTask(reply,ID,name,_self);
|
|
|
m_pendingTasks->append(task);
|
|
|
connect(task, SIGNAL(gotHead(FileDownloaderTask*,QNetworkReply*)), _self, SLOT(gotHead(FileDownloaderTask*,QNetworkReply*)));
|
|
|
if(!_self->m_noGui)
|
|
|
{
|
|
|
m_DownLoadHistory->addElement(new DownloadHistoryElement(task));
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return -1;
|
|
|
}
|
|
|
}
|
|
|
return ID;
|
|
|
}
|
|
|
|
|
|
int FileDownloader::downloadFile(QString fileUrl, const QString &name)
|
|
|
{
|
|
|
return downloadFile(QUrl(fileUrl),name);
|
|
|
}
|
|
|
|
|
|
QDockWidget *FileDownloader::getGUI()
|
|
|
{
|
|
|
if(!_self->m_noGui && (m_gui==NULL))
|
|
|
{
|
|
|
m_DownLoadHistory=new DownLoadHistory();
|
|
|
m_gui=new QDockWidget("Download History");
|
|
|
m_gui->setWidget(m_DownLoadHistory);
|
|
|
m_gui->setFeatures(QDockWidget::DockWidgetMovable|QDockWidget::DockWidgetFloatable);
|
|
|
m_SettingsGui = new FileDowloaderSettingsGUI();
|
|
|
QLopSettings::registerConfigEntry(this->m_SettingsGui,QIcon(":/img/Gnome-emblem-downloads.svg"),"Qlop Downloader");
|
|
|
}
|
|
|
return (QDockWidget*) m_gui;
|
|
|
}
|
|
|
|
|
|
const QString &FileDownloader::serviceName()
|
|
|
{
|
|
|
return m_serviceName;
|
|
|
}
|
|
|
|
|
|
int FileDownloader::download_file(QUrl fileUrl, const QString &name)
|
|
|
{
|
|
|
return downloadFile(fileUrl,name);
|
|
|
}
|
|
|
|
|
|
int FileDownloader::download_file(QString fileUrl, const QString &name)
|
|
|
{
|
|
|
return downloadFile(fileUrl,name);
|
|
|
}
|
|
|
|
|
|
void FileDownloader::gotHead(FileDownloaderTask* task,QNetworkReply* headerreply)
|
|
|
{
|
|
|
QNetworkReply* reply;
|
|
|
QByteArray rangeHeaderValue;
|
|
|
bool acceptRestart=false;
|
|
|
int DownloadTotalFileSize = headerreply->header(QNetworkRequest::ContentLengthHeader).toInt();
|
|
|
if (headerreply->hasRawHeader("Accept-Ranges"))
|
|
|
{
|
|
|
QString qstrAcceptRanges = headerreply->rawHeader("Accept-Ranges");
|
|
|
acceptRestart = (qstrAcceptRanges.compare("bytes", Qt::CaseInsensitive) == 0);
|
|
|
rangeHeaderValue = "bytes=" + QByteArray::number(task->startPosition()) + "-";
|
|
|
if (DownloadTotalFileSize > 0)
|
|
|
{
|
|
|
rangeHeaderValue += QByteArray::number(DownloadTotalFileSize);
|
|
|
}
|
|
|
}
|
|
|
QNetworkRequest request(headerreply->request());
|
|
|
delete headerreply;
|
|
|
request.setRawHeader("Connection", "Keep-Alive");
|
|
|
if(acceptRestart)
|
|
|
request.setRawHeader("Range", rangeHeaderValue);
|
|
|
request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true);
|
|
|
reply = m_WebCtrl->get(request);
|
|
|
task->restart(reply,acceptRestart);
|
|
|
}
|
|
|
|
|
|
void FileDownloader::configureProxy()
|
|
|
{
|
|
|
// QString proxyType = QLopSettings::value(FileDownloader::self(),"proxy/type","none").toString();
|
|
|
// if(proxyType=="none")
|
|
|
// {
|
|
|
// QNetworkProxy proxy;
|
|
|
// proxy.setType(QNetworkProxy::Socks5Proxy);
|
|
|
// proxy.setHostName("proxy.example.com");
|
|
|
// proxy.setPort(1080);
|
|
|
// proxy.setUser("username");
|
|
|
// proxy.setPassword("password");
|
|
|
// QNetworkProxy::setApplicationProxy(proxy);
|
|
|
// }
|
|
|
// QNetworkProxyQuery q(QUrl(QLatin1String("http://www.google.com")));
|
|
|
// QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery(q);
|
|
|
// foreach ( QNetworkProxy loopItem, proxies ) {
|
|
|
// qDebug() << "proxyUsed:" << loopItem.hostName();
|
|
|
// }
|
|
|
// if( proxies.size() > 0 && proxies[0].type() != QNetworkProxy::NoProxy )
|
|
|
// QNetworkProxy::setApplicationProxy(proxies[0]);
|
|
|
// else
|
|
|
// qDebug("No proxy server selected");
|
|
|
}
|
|
|
|
|
|
FileDownloaderTask* FileDownloader::getDownloadTask(int ID)
|
|
|
{
|
|
|
_INIT
|
|
|
for(int i=0;i<m_pendingTasks->count();i++)
|
|
|
{
|
|
|
if(m_pendingTasks->at(i)->ID()==ID)
|
|
|
return m_pendingTasks->at(i);
|
|
|
}
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
bool FileDownloader::taskIsCompleted(int ID)
|
|
|
{
|
|
|
return getDownloadTask(ID)->downloadComplete();
|
|
|
}
|
|
|
|
|
|
FileDownloader *FileDownloader::self()
|
|
|
{
|
|
|
_INIT
|
|
|
|
|
|
return _self;
|
|
|
|
|
|
}
|
|
|
|
|
|
void FileDownloader::reloadConfig()
|
|
|
{
|
|
|
m_ProxyFactory->reloadConfig();
|
|
|
}
|
|
|
|
|
|
int FileDownloader::getTaskId()
|
|
|
{
|
|
|
for(unsigned int i=0;i<INT_MAX;i++)
|
|
|
{
|
|
|
bool idValid=true;
|
|
|
for(int j=0;j<m_pendingTasks->count();j++)
|
|
|
{
|
|
|
if(m_pendingTasks->at(j)->ID()==(int)i)
|
|
|
idValid=false;
|
|
|
}
|
|
|
if(idValid)
|
|
|
return (int)i;
|
|
|
}
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
void FileDownloader::init(bool noGUI, QObject *parent)
|
|
|
{
|
|
|
if(Q_UNLIKELY(_self==NULL))
|
|
|
{
|
|
|
_self=new FileDownloader(noGUI,parent);
|
|
|
_self->reloadConfig();
|
|
|
}
|
|
|
}
|
|
|
/*for gnome:
|
|
|
*
|
|
|
* gsettings list-recursively org.gnome.system.proxy
|
|
|
* gsettings get org.gnome.system.proxy.http host
|
|
|
*
|
|
|
* To detect desktop $XDG_CURRENT_DESKTOP
|
|
|
*/
|
|
|
FileDownloader::FileDownloader(bool noGUI,QObject *parent) : QLopService(parent)
|
|
|
{
|
|
|
m_ProxyFactory = new QLopNetworkProxyFactory();
|
|
|
// configureProxy();
|
|
|
m_WebCtrl = new QNetworkAccessManager(this);
|
|
|
m_WebCtrl->setProxyFactory(m_ProxyFactory);
|
|
|
m_pendingTasks = new QList<FileDownloaderTask*>();
|
|
|
m_noGui=noGUI;
|
|
|
m_serviceName="FileDownloader";
|
|
|
}
|
|
|
|
|
|
FileDownloader::~FileDownloader()
|
|
|
{
|
|
|
if(!m_noGui)
|
|
|
delete m_gui;
|
|
|
while (m_pendingTasks->count())
|
|
|
{
|
|
|
FileDownloaderTask* task=m_pendingTasks->last();
|
|
|
m_pendingTasks->removeLast();
|
|
|
delete task;
|
|
|
}
|
|
|
delete m_WebCtrl;
|
|
|
}
|
|
|
|