]> git.sur5r.net Git - minitube/blob - src/downloadmanager.cpp
6944e1639f77c87d4c9374fb66970c795160ac41
[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     int row = items.count();
121     downloadModel->beginInsertRows(QModelIndex(), row, row);
122     items.append(item);
123     downloadModel->endInsertRows();
124
125     // connect(item, SIGNAL(statusChanged()), SLOT(updateStatusMessage()));
126     connect(item, SIGNAL(finished()), SLOT(itemFinished()));
127     item->start();
128
129     updateStatusMessage();
130 }
131
132 void DownloadManager::itemFinished() {
133     if (activeItems() == 0) emit finished();
134 }
135
136 void DownloadManager::updateStatusMessage() {
137     QString message = tr("%n Download(s)", "", items.size());
138     emit statusMessageChanged(message);
139 }
140
141 QString DownloadManager::defaultDownloadFolder() {
142     // download in the Movies system folder
143     QString path = QDesktopServices::storageLocation(QDesktopServices::MoviesLocation);
144     QDir moviesDir(path);
145     if (!moviesDir.exists()) {
146         // fallback to Desktop
147         path = QDesktopServices::storageLocation(QDesktopServices::DesktopLocation);
148
149         QDir desktopDir(path);
150         if (!desktopDir.exists()) {
151             // fallback to Home
152             path = QDesktopServices::storageLocation(QDesktopServices::HomeLocation);
153         }
154     }
155     return path;
156 }
157
158 QString DownloadManager::currentDownloadFolder() {
159     QSettings settings;
160     QString path = settings.value("downloadFolder").toString();
161     if (path.isEmpty()) path = defaultDownloadFolder();
162     return path;
163 }