]> git.sur5r.net Git - minitube/blob - src/downloadmanager.cpp
Imported Upstream version 1.9
[minitube] / src / downloadmanager.cpp
1 #include "downloadmanager.h"
2 #include "downloaditem.h"
3 #include "downloadmodel.h"
4 #include "video.h"
5 #include "constants.h"
6 #include "MainWindow.h"
7
8 static DownloadManager *downloadManagerInstance = 0;
9
10 DownloadManager::DownloadManager(QWidget *parent) :
11     QObject(parent),
12     downloadModel(new DownloadModel(this, this))
13 { }
14
15 DownloadManager* DownloadManager::instance() {
16     if (!downloadManagerInstance) downloadManagerInstance = new DownloadManager();
17     return downloadManagerInstance;
18 }
19
20 void DownloadManager::clear() {
21     qDeleteAll(items);
22     items.clear();
23     updateStatusMessage();
24 }
25
26 int DownloadManager::activeItems() {
27     int num = 0;
28     foreach (DownloadItem *item, items) {
29         if (item->status() == Downloading || item->status() == Starting) num++;
30     }
31     return num;
32 }
33
34 DownloadItem* DownloadManager::itemForVideo(Video* video) {
35     foreach (DownloadItem *item, items) {
36         if (item->getVideo()->id() == video->id()) return item;
37     }
38     return 0;
39 }
40
41 void DownloadManager::addItem(Video *video) {
42     // qDebug() << __FUNCTION__ << video->title();
43
44 #ifdef APP_DEMO
45     if (video->duration() >= 60*4) {
46         QMessageBox msgBox(MainWindow::instance());
47         msgBox.setIconPixmap(QPixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
48         msgBox.setText(tr("This is just the demo version of %1.").arg(Constants::NAME));
49         msgBox.setInformativeText(
50                     tr("It can only download videos shorter than %1 minutes so you can test the download functionality.")
51                     .arg(4));
52         msgBox.setModal(true);
53         // make it a "sheet" on the Mac
54         msgBox.setWindowModality(Qt::WindowModal);
55
56         msgBox.addButton(tr("Continue"), QMessageBox::RejectRole);
57         QPushButton *buyButton = msgBox.addButton(tr("Get the full version"), QMessageBox::ActionRole);
58
59         msgBox.exec();
60
61         if (msgBox.clickedButton() == buyButton) {
62             QDesktopServices::openUrl(QUrl(QString(Constants::WEBSITE) + "#download"));
63         }
64
65         return;
66     }
67 #endif
68
69     DownloadItem *item = itemForVideo(video);
70     if (item != 0) {
71         if (item->status() == Failed || item->status() == Idle) {
72             qDebug() << "Restarting download" << video->title();
73             item->tryAgain();
74         } else {
75             qDebug() << "Already downloading video" << video->title();
76         }
77         return;
78     }
79
80     connect(video, SIGNAL(gotStreamUrl(QUrl)), SLOT(gotStreamUrl(QUrl)));
81     // TODO handle signal errors
82     // connect(video, SIGNAL(errorStreamUrl(QString)), SLOT(handleError(QString)));
83     video->loadStreamUrl();
84
85     // see you in gotStreamUrl()
86 }
87
88 void DownloadManager::gotStreamUrl(QUrl url) {
89
90     Video *video = static_cast<Video*>(sender());
91     if (!video) {
92         qDebug() << "Cannot get video in" << __FUNCTION__;
93         return;
94     }
95
96     video->disconnect(this);
97
98     QString path = currentDownloadFolder();
99
100     // TODO ensure all chars are filename compatible
101     QString basename = video->title();
102     basename.replace('(', '[');
103     basename.replace(')', ']');
104     basename.replace('/', ' ');
105     basename.replace('\\', ' ');
106     basename.replace('<', ' ');
107     basename.replace('>', ' ');
108     basename.replace(':', ' ');
109     basename.replace('"', ' ');
110     basename.replace('|', ' ');
111     basename.replace('?', ' ');
112     basename.replace('*', ' ');
113     basename = basename.simplified();
114
115     QString filename = path + "/" + basename + ".mp4";
116
117     Video *videoCopy = video->clone();
118     DownloadItem *item = new DownloadItem(videoCopy, url, filename, this);
119
120     downloadModel->beginInsertRows(QModelIndex(), 0, 0);
121     items.prepend(item);
122     downloadModel->endInsertRows();
123
124     // connect(item, SIGNAL(statusChanged()), SLOT(updateStatusMessage()));
125     connect(item, SIGNAL(finished()), SLOT(itemFinished()));
126     item->start();
127
128     updateStatusMessage();
129 }
130
131 void DownloadManager::itemFinished() {
132     if (activeItems() == 0) emit finished();
133 #ifdef Q_WS_MAC
134     if (mac::canNotify()) {
135         DownloadItem *item = static_cast<DownloadItem*>(sender());
136         if (!item) {
137             qDebug() << "Cannot get item in" << __FUNCTION__;
138             return;
139         }
140         Video *video = item->getVideo();
141         if (!video) return;
142         QString stats = tr("%1 downloaded in %2").arg(
143                     DownloadItem::formattedFilesize(item->bytesTotal()),
144                     DownloadItem::formattedTime(item->totalTime(), false));
145         mac::notify(tr("Download finished"), video->title(), stats);
146     }
147 #endif
148 }
149
150 void DownloadManager::updateStatusMessage() {
151     QString message = tr("%n Download(s)", "", items.size());
152     emit statusMessageChanged(message);
153 }
154
155 QString DownloadManager::defaultDownloadFolder() {
156     // download in the Movies system folder
157     QString path = QDesktopServices::storageLocation(QDesktopServices::MoviesLocation);
158     QDir moviesDir(path);
159     if (!moviesDir.exists()) {
160         // fallback to Desktop
161         path = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation);
162
163         QDir desktopDir(path);
164         if (!desktopDir.exists()) {
165             // fallback to Home
166             path = QDesktopServices::storageLocation(QDesktopServices::HomeLocation);
167         }
168     }
169     return path;
170 }
171
172 QString DownloadManager::currentDownloadFolder() {
173     QSettings settings;
174     QString path = settings.value("downloadFolder").toString();
175     if (path.isEmpty()) path = defaultDownloadFolder();
176     return path;
177 }