]> git.sur5r.net Git - minitube/blob - src/downloadmanager.cpp
history stack as non-pointer member
[minitube] / src / downloadmanager.cpp
1 /* $BEGIN_LICENSE
2
3 This file is part of Minitube.
4 Copyright 2009, Flavio Tordini <flavio.tordini@gmail.com>
5
6 Minitube is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 Minitube is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Minitube.  If not, see <http://www.gnu.org/licenses/>.
18
19 $END_LICENSE */
20
21 #include "downloadmanager.h"
22 #include "downloaditem.h"
23 #include "downloadmodel.h"
24 #include "video.h"
25 #include "constants.h"
26 #include "mainwindow.h"
27 #ifdef APP_ACTIVATION
28 #include "activation.h"
29 #endif
30 #ifdef APP_EXTRA
31 #include "extra.h"
32 #endif
33 #include "datautils.h"
34 #include "compatibility/pathsservice.h"
35
36 static DownloadManager *downloadManagerInstance = 0;
37
38 DownloadManager::DownloadManager(QWidget *parent) :
39     QObject(parent),
40     downloadModel(new DownloadModel(this, this))
41 { }
42
43 DownloadManager* DownloadManager::instance() {
44     if (!downloadManagerInstance) downloadManagerInstance = new DownloadManager();
45     return downloadManagerInstance;
46 }
47
48 void DownloadManager::clear() {
49     qDeleteAll(items);
50     items.clear();
51     updateStatusMessage();
52 }
53
54 int DownloadManager::activeItems() {
55     int num = 0;
56     foreach (DownloadItem *item, items) {
57         if (item->status() == Downloading || item->status() == Starting) num++;
58     }
59     return num;
60 }
61
62 DownloadItem* DownloadManager::itemForVideo(Video* video) {
63     foreach (DownloadItem *item, items) {
64         if (item->getVideo()->id() == video->id()) return item;
65     }
66     return 0;
67 }
68
69 void DownloadManager::addItem(Video *video) {
70     // qDebug() << __FUNCTION__ << video->title();
71
72 #ifdef APP_ACTIVATION
73     if (!Activation::instance().isActivated()) {
74         if (video->duration() >= 60*4) {
75             QMessageBox msgBox(MainWindow::instance());
76             msgBox.setIconPixmap(QPixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
77             msgBox.setText(tr("This is just the demo version of %1.").arg(Constants::NAME));
78             msgBox.setInformativeText(
79                         tr("It can only download videos shorter than %1 minutes so you can test the download functionality.")
80                         .arg(4));
81             msgBox.setModal(true);
82             // make it a "sheet" on the Mac
83             msgBox.setWindowModality(Qt::WindowModal);
84
85             msgBox.addButton(tr("Continue"), QMessageBox::RejectRole);
86             QPushButton *buyButton = msgBox.addButton(tr("Get the full version"), QMessageBox::ActionRole);
87
88             msgBox.exec();
89
90             if (msgBox.clickedButton() == buyButton) {
91                 MainWindow::instance()->showActivationView();
92             }
93
94             return;
95         }
96     }
97 #endif
98
99     DownloadItem *item = itemForVideo(video);
100     if (item != 0) {
101         if (item->status() == Failed || item->status() == Idle) {
102             qDebug() << "Restarting download" << video->title();
103             item->tryAgain();
104         } else {
105             qDebug() << "Already downloading video" << video->title();
106         }
107         return;
108     }
109
110     connect(video, SIGNAL(gotStreamUrl(QUrl)), SLOT(gotStreamUrl(QUrl)));
111     // TODO handle signal errors
112     // connect(video, SIGNAL(errorStreamUrl(QString)), SLOT(handleError(QString)));
113     video->loadStreamUrl();
114
115     // see you in gotStreamUrl()
116 }
117
118 void DownloadManager::gotStreamUrl(QUrl url) {
119
120     Video *video = static_cast<Video*>(sender());
121     if (!video) {
122         qDebug() << "Cannot get video in" << __FUNCTION__;
123         return;
124     }
125
126     video->disconnect(this);
127
128     QString basename = DataUtils::stringToFilename(video->title());
129     if (basename.isEmpty()) basename = video->id();
130
131     QString filename = currentDownloadFolder() + "/" + basename + ".mp4";
132
133     Video *videoCopy = video->clone();
134     DownloadItem *item = new DownloadItem(videoCopy, url, filename, this);
135
136     downloadModel->beginInsertRows(QModelIndex(), 0, 0);
137     items.prepend(item);
138     downloadModel->endInsertRows();
139
140     // connect(item, SIGNAL(statusChanged()), SLOT(updateStatusMessage()));
141     connect(item, SIGNAL(finished()), SLOT(itemFinished()));
142     item->start();
143
144     updateStatusMessage();
145 }
146
147 void DownloadManager::itemFinished() {
148     if (activeItems() == 0) emit finished();
149 #ifdef APP_EXTRA
150     DownloadItem *item = static_cast<DownloadItem*>(sender());
151     if (!item) {
152         qDebug() << "Cannot get item in" << __FUNCTION__;
153         return;
154     }
155     Video *video = item->getVideo();
156     if (!video) return;
157     QString stats = tr("%1 downloaded in %2").arg(
158                 DownloadItem::formattedFilesize(item->bytesTotal()),
159                 DownloadItem::formattedTime(item->totalTime(), false));
160     Extra::notify(tr("Download finished"), video->title(), stats);
161 #endif
162 }
163
164 void DownloadManager::updateStatusMessage() {
165     QString message = tr("%n Download(s)", "", activeItems());
166     emit statusMessageChanged(message);
167 }
168
169 QString DownloadManager::defaultDownloadFolder() {
170     // download in the Movies system folder
171     QString path = Paths::getMoviesLocation();
172
173     const QDir moviesDir(path);
174     if (!moviesDir.exists()) {
175         // fallback to Desktop
176         path = Paths::getDesktopLocation();
177
178         const QDir desktopDir(path);
179         if (!desktopDir.exists()) {
180             // fallback to Home
181             path = Paths::getHomeLocation();
182         }
183     }
184     return path;
185 }
186
187 QString DownloadManager::currentDownloadFolder() {
188     QSettings settings;
189     QString path = settings.value("downloadFolder").toString();
190     if (path.isEmpty()) path = defaultDownloadFolder();
191     return path;
192 }