]> git.sur5r.net Git - minitube/blob - src/downloadmanager.cpp
Imported Upstream version 1.4.3
[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
7 static DownloadManager *downloadManagerInstance = 0;
8
9 DownloadManager::DownloadManager(QWidget *parent) :
10         QObject(parent),
11         downloadModel(new DownloadModel(this, this))
12 { }
13
14 DownloadManager* DownloadManager::instance() {
15     if (!downloadManagerInstance) downloadManagerInstance = new DownloadManager();
16     return downloadManagerInstance;
17 }
18
19 void DownloadManager::clear() {
20     qDeleteAll(items);
21     items.clear();
22     updateStatusMessage();
23 }
24
25 int DownloadManager::activeItems() {
26     int num = 0;
27     foreach (DownloadItem *item, items) {
28         if (item->status() == Downloading || item->status() == Starting) num++;
29     }
30     return num;
31 }
32
33 DownloadItem* DownloadManager::itemForVideo(Video* video) {
34     foreach (DownloadItem *item, items) {
35         if (item->getVideo()->id() == video->id()) return item;
36     }
37     return 0;
38 }
39
40 void DownloadManager::addItem(Video *video) {
41     // qDebug() << __FUNCTION__ << video->title();
42     
43 #ifdef APP_DEMO
44     if (video->duration() >= 60*4) {
45         QMessageBox msgBox(dynamic_cast<QWidget*>(parent())->window());
46         msgBox.setIconPixmap(QPixmap(":/images/app.png").scaled(64, 64, Qt::KeepAspectRatio, Qt::SmoothTransformation));
47         msgBox.setText(tr("This is just the demo version of %1.").arg(Constants::APP_NAME));
48         msgBox.setInformativeText(
49                 tr("It can only download videos shorter than %1 minutes so you can test the download functionality.")
50                 .arg(4));
51         msgBox.setModal(true);
52         // make it a "sheet" on the Mac
53         msgBox.setWindowModality(Qt::WindowModal);
54
55         QPushButton *quitButton = msgBox.addButton(tr("Continue"), QMessageBox::RejectRole);
56         QPushButton *buyButton = msgBox.addButton(tr("Get the full version"), QMessageBox::ActionRole);
57
58         msgBox.exec();
59
60         if (msgBox.clickedButton() == buyButton) {
61             QDesktopServices::openUrl(QString(Constants::WEBSITE) + "#download");
62         }
63
64         return;
65     }
66 #endif
67     
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 }