initial
[nomnom.git] / src / Download.cpp
blob16092d3ddbdab1f384d24d79173c97c46a8eb1a1
1 /*
2 * Copyright (C) 2010 Toni Gundogdu.
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #include <QDebug>
20 #include "util.h"
21 #include "Log.h"
22 #include "Download.h"
24 // main.cpp
25 extern Log log;
27 Download::Download (QWidget *parent/*=NULL*/)
28 : QProgressDialog (parent)
31 #define _wrap(s,sl) \
32 do { connect (&_proc, SIGNAL(s), this, SLOT(sl)); } while (0)
34 _wrap (started (), onCurlStarted ());
36 _wrap (error (QProcess::ProcessError),
37 onCurlError (QProcess::ProcessError));
39 _wrap (readyRead (), onCurlReadyRead ());
41 _wrap (finished (int, QProcess::ExitStatus),
42 onCurlFinished (int, QProcess::ExitStatus));
44 #undef _wrap
46 connect (this, SIGNAL(canceled()), this, SLOT (onCanceled()));
48 setWindowModality (Qt::WindowModal);
49 setAutoClose (false);
52 void
53 Download::start (const QString& cmd, const QString& fpath, Video *video) {
55 #ifdef _0
56 qDebug () << __PRETTY_FUNCTION__;
57 #endif
59 Q_ASSERT (!cmd.isEmpty ());
60 Q_ASSERT (!fpath.isEmpty ());
61 Q_ASSERT (video != NULL);
63 _lastError.clear ();
65 QStringList args = cmd.split (" ");
67 args.replaceInStrings ("%u", video->get (Video::Link).toString ());
68 args.replaceInStrings ("%f", fpath);
70 log << args.join (" ") + "\n";
72 _proc.setProcessChannelMode (QProcess::MergedChannels);
74 show ();
75 _proc.start (args.takeFirst (), args);
76 exec ();
79 void
80 Download::onCurlStarted ()
81 { setLabelText (tr ("Starting download ...")); }
83 void
84 Download::onCurlError (QProcess::ProcessError n) {
85 #ifdef _0
86 qDebug () << __PRETTY_FUNCTION__;
87 #endif
88 emit error (NomNom::to_process_errmsg (n));
89 cancel ();
92 static const QRegExp rx_prog ("^(\\d+).*(\\d+:\\d+:\\d+|\\d+d \\d+h)\\s+(\\w+)$");
93 static const QRegExp rx_err ("curl:\\s+(.*)$");
94 static const QRegExp rx_rate ("(\\D+)"); // rate unit
96 void
97 Download::onCurlReadyRead () {
99 #ifdef _0
100 qDebug () << __PRETTY_FUNCTION__;
101 #endif
103 static char data[1024];
105 while (_proc.readLine (data, sizeof (data))) {
107 QString ln = QString::fromLocal8Bit (data).simplified ();
109 if (rx_err.indexIn (ln) != -1) {
110 _lastError = "curl: " +rx_err.cap (1);
111 continue;
114 if (ln.split (" ").count () < 12)
115 continue; // Full line updates only, PLZKTHXBYE.
117 #ifdef _0
118 qDebug () << ln;
119 qDebug () << "--";
120 #endif
122 if (rx_prog.indexIn (ln) != -1) {
124 enum {
125 PERCENT = 1,
126 ETA,
127 RATE
130 #ifdef _0
131 qDebug ()
132 << rx_prog.cap (PERCENT)
133 << rx_prog.cap (ETA)
134 << rx_prog.cap (RATE);
135 qDebug ()
136 << ln;
137 #endif
139 setValue (rx_prog.cap (PERCENT).toInt ());
141 QString rate = rx_prog.cap (RATE);
143 if (rx_rate.indexIn (rate) == -1) {
144 rate = QString ("%1k").arg (rate.toLongLong ()/1024.0,2,'f',1);
147 const QString s = tr("Copying at %1, %2")
148 .arg (rate)
149 .arg (rx_prog.cap (ETA))
152 setLabelText (s);
155 else
156 log << ln;
162 void
163 Download::onCurlFinished (int exitCode, QProcess::ExitStatus es) {
165 #ifdef _0
166 qDebug () << __PRETTY_FUNCTION__;
167 #endif
169 switch (es) {
171 case QProcess::NormalExit:
173 switch (exitCode) {
175 default: emit error (_lastError); break;
177 case 0: break;
179 } // Switch exitCode.
181 break; // NormalExit.
183 default: break;
185 } // Switch ExitStatus.
187 cancel ();
190 void
191 Download::onCanceled () {
193 #ifdef _0
194 qDebug () << __PRETTY_FUNCTION__;
195 #endif
197 if (_proc.state () == QProcess::Running)
198 _proc.kill ();