1 /*
2  * Hydrogen
3  * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net]
4  *
5  * http://www.hydrogen-music.org
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY, without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  */
22 
23 #include "DownloadWidget.h"
24 
25 #include <cmath>
26 #include <cstdlib>
27 #include <QNetworkReply>
28 
29 const char* Download::__class_name = "Download";
30 
Download(QWidget * pParent,const QString & download_url,const QString & local_file)31 Download::Download( QWidget* pParent, const QString& download_url, const QString& local_file )
32 		: QDialog( pParent )
33 		, Object( __class_name )
34 		, __download_percent( 0 )
35 		, __eta( 0 )
36 		, __bytes_current( 0 )
37 		, __bytes_total( 0 )
38 		, __remote_url( download_url )
39 		, __local_file( local_file )
40 		, __reply(nullptr)
41 		, __error(false)
42 {
43 	if ( !__local_file.isEmpty() ) {
44 		INFOLOG( QString( "Downloading '%1' in '%2'" ).arg( __remote_url.toString() ).arg( __local_file ) );
45 	} else {
46 		INFOLOG( QString( "Downloading '%1'" ).arg( __remote_url.toString() ) );
47 	}
48 
49 	__http_client = new QNetworkAccessManager(this);
50 
51 	QString sEnvHttpProxy		= QString( getenv( "http_proxy" ) );
52 	int     nEnvHttpPort		= 0;
53 	QString sEnvHttpUser		= QString( getenv( "http_user" ) );
54 	QString sEnvHttpPassword	= QString( getenv( "http_password" ) );
55 
56 	nEnvHttpPort	= sEnvHttpProxy.right( sEnvHttpProxy.length() - sEnvHttpProxy.indexOf(':') - 1 ).toInt();
57 	sEnvHttpProxy	= sEnvHttpProxy.left( sEnvHttpProxy.indexOf(':') );
58 
59 	__time.start();
60 
61 	if ( ( !sEnvHttpProxy.isNull() ) && ( nEnvHttpPort != 0 ) ) {
62 		QNetworkProxy proxy;
63 		proxy.setType( QNetworkProxy::DefaultProxy );
64 		proxy.setHostName( sEnvHttpProxy );
65 		proxy.setPort( nEnvHttpPort );
66 		proxy.setUser( sEnvHttpUser );
67 		proxy.setPassword( sEnvHttpPassword );
68 		__http_client->setProxy(proxy);
69 	}
70 
71 	QNetworkRequest getReq;
72 	getReq.setUrl( __remote_url );
73 	getReq.setRawHeader( "User-Agent" , "Hydrogen" );
74 
75 	__reply = __http_client->get( getReq );
76 
77 	connect(__reply, SIGNAL(finished()),this, SLOT(finished()));
78 	connect(__reply, SIGNAL(downloadProgress(qint64,qint64)), this, SLOT(downloadProgress(qint64,qint64)));
79 }
80 
81 
82 
~Download()83 Download::~Download()
84 {
85 }
86 
87 /// TODO: I have to save the file to disk on a temporary dir and then move it if everything is ok.
finished()88 void Download::finished()
89 {
90 	if ( __reply->error() ) {
91 		__error = true;
92 		ERRORLOG(QString( tr( "Importing item failed: %1" ) ).arg( __reply->errorString() ));
93 		QMessageBox::information( this, "Hydrogen", QString( tr( "Importing item failed: %1" ) ).arg( __reply->errorString() ) );
94 		reject();
95 		return;
96 	}
97 
98 
99 	int StatusAttribute = __reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
100 	if(StatusAttribute >= 200 && StatusAttribute < 300){
101 		//do nothing, handling will be done later..
102 	} else if(StatusAttribute >= 300 && StatusAttribute < 400){
103 		QVariant RedirectAttribute = __reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
104 
105 		if ( RedirectAttribute != 0 ) {
106 
107 			__redirect_url = __remote_url.resolved(RedirectAttribute.toUrl());
108 			__reply->deleteLater();
109 			INFOLOG( QString( "Download redirected to '%1'" ).arg( __redirect_url.toString() ) );
110 
111 			reject();
112 			return;
113 		}
114 	}
115 
116 	INFOLOG( "Download completed. " );
117 
118 	if ( __local_file.isEmpty() ) {
119 		// store the text received only when not using the file.
120 		__feed_xml_string = QString( __reply->readAll() );
121 	} else {
122 		QFile file( __local_file );
123 
124 		if ( !file.open( QIODevice::WriteOnly ) ) {
125 			ERRORLOG( QString( "Unable to save %1" ).arg( __local_file ) );
126 		} else {
127 			file.write(__reply->readAll());
128 			file.flush();
129 			file.close();
130 		}
131 	}
132 	accept();
133 }
134 
135 
136 
downloadProgress(qint64 done,qint64 total)137 void Download::downloadProgress( qint64 done, qint64 total )
138 {
139 	__bytes_current = done;
140 	__bytes_total = total;
141 
142 	__download_percent = ( float )done / ( float )total * 100.0;
143 }
144 
145 
146 // :::::::::::::::::::..
147 
148 
149 
DownloadWidget(QWidget * parent,const QString & title,const QString & __remote_url,const QString & local_file)150 DownloadWidget::DownloadWidget( QWidget* parent, const QString& title, const QString& __remote_url, const QString& local_file )
151 		: Download( parent, __remote_url, local_file )
152 {
153 	setWindowTitle( title );
154 	setModal( true );
155 
156 	setFixedSize( 500, 100 );
157 
158 	QFont boldFont;
159 	boldFont.setBold( true );
160 
161 	__url_label = new QLabel( nullptr );
162 	__url_label->setFont( boldFont );
163 	__url_label->setAlignment( Qt::AlignCenter );
164 	__url_label->setText( QFileInfo( __remote_url ).fileName() );
165 
166 	__progress_bar = new QProgressBar( nullptr );
167 
168 	__progress_bar->setMinimum( 0 );
169 	__progress_bar->setMaximum( 100 );
170 
171 	__eta_label = new QLabel( nullptr );
172 	__eta_label->setAlignment( Qt::AlignHCenter );
173 
174 
175 	QVBoxLayout* pVBox = new QVBoxLayout();
176 	pVBox->addWidget( __url_label );
177 	pVBox->addWidget( __progress_bar );
178 	pVBox->addWidget( __eta_label );
179 
180 
181 	setLayout( pVBox );
182 
183 	__update_timer = new QTimer( this );
184 	connect( __update_timer, SIGNAL( timeout() ), this, SLOT( updateStats() ) );
185 
186 	__close_timer = new QTimer( this );
187 	connect( __close_timer, SIGNAL( timeout() ), this, SLOT( close() ) );
188 
189 	__update_timer->start( 100 );
190 }
191 
192 
193 
~DownloadWidget()194 DownloadWidget::~DownloadWidget()
195 {
196 	__update_timer->stop();
197 	__close_timer->stop();
198 }
199 
200 
201 
updateStats()202 void DownloadWidget::updateStats()
203 {
204 	if ( __download_percent > 0 ) {
205 		__eta = ( int )( round( ( __time.elapsed() / __download_percent * ( 100 - __download_percent ) ) / 1000 ) );
206 	}
207 
208 	__progress_bar->setValue( get_percent_done() );
209 
210 	QString hours = QString( "%1" ).arg( __eta / 60 / 60 );
211 	QString minutes = QString( "%1" ).arg( ( __eta / 60 ) % 60 );
212 	QString seconds = QString( "%1" ).arg( __eta % 60 );
213 
214 	hours = hours.rightJustified( 2, '0' );
215 	minutes = minutes.rightJustified( 2, '0' );
216 	seconds = seconds.rightJustified( 2, '0' );
217 
218 	QString sETA = hours + ":" + minutes + ":" + seconds;
219 
220 	__eta_label->setText( tr( "(%1/%2 KiB) - ETA %3" ).arg( __bytes_current / 1024 ).arg( __bytes_total / 1024 ).arg( sETA ) );
221 
222 	if ( __download_percent == 100 ) {
223 		__update_timer->stop();
224 
225 		__close_timer->start( 1000 ); // close the window after 1 second
226 	}
227 }
228 
229