filedownloader.cpp
237 lines
| 7.3 KiB
| text/x-c
|
CppLexer
r16 | /*------------------------------------------------------------------------------ | |||
-- 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; | ||||
} | ||||