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