File indexing completed on 2024-05-05 04:59:19
0001 /* 0002 This file is part of the KDE project 0003 Copyright (C) 2011 Ernesto Rodriguez Ortiz <eortiz@uci.cu> 0004 0005 This program is free software: you can redistribute it and/or modify 0006 it under the terms of the GNU General Public License as published by 0007 the Free Software Foundation, either version 3 of the License, or 0008 (at your option) any later version. 0009 0010 This program is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 GNU General Public License for more details. 0014 0015 You should have received a copy of the GNU General Public License 0016 along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 0018 */ 0019 0020 #include "mmstransfer.h" 0021 0022 #include "kget_debug.h" 0023 #include <QDebug> 0024 #include <QDir> 0025 #include <QStandardPaths> 0026 0027 MmsTransfer::MmsTransfer(TransferGroup *parent, TransferFactory *factory, Scheduler *scheduler, const QUrl &source, const QUrl &dest, const QDomElement *e) 0028 : Transfer(parent, factory, scheduler, source, dest, e) 0029 , m_mmsdownload(NULL) 0030 , m_amountThreads(MmsSettings::threads()) 0031 , m_retryDownload(false) 0032 { 0033 // make sure that the DataLocation directory exists (earlier this used to be handled by KStandardDirs) 0034 if (!QFileInfo::exists(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation))) { 0035 QDir().mkpath(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); 0036 } 0037 m_fileTemp = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QLatin1Char('/') + m_dest.fileName(); 0038 qCDebug(KGET_DEBUG) << "Mms transfer initialized: " + m_source.toString(); 0039 } 0040 0041 MmsTransfer::~MmsTransfer() 0042 { 0043 /** If m_mmsdownload is not deleted we delete it before end.*/ 0044 if (m_mmsdownload) { 0045 m_mmsdownload->quit(); 0046 m_mmsdownload->deleteLater(); 0047 } 0048 } 0049 0050 void MmsTransfer::start() 0051 { 0052 /** Starting the download, is created the thread m_mmsdownload and is started the download*/ 0053 if (m_mmsdownload || status() == Finished) { 0054 return; 0055 } 0056 0057 setStatus(Job::Running, i18nc("transfer state: running", "Running...."), "media-playback-start"); 0058 m_mmsdownload = new MmsDownload(m_source.toString(), m_dest.toLocalFile(), m_fileTemp, m_amountThreads); 0059 connect(m_mmsdownload, SIGNAL(finished()), this, SLOT(slotResult())); 0060 connect(m_mmsdownload, SIGNAL(signBrokenUrl()), this, SLOT(slotBrokenUrl())); 0061 connect(m_mmsdownload, SIGNAL(signNotAllowMultiDownload()), this, SLOT(slotNotAllowMultiDownload())); 0062 connect(m_mmsdownload, SIGNAL(signTotalSize(qulonglong)), this, SLOT(slotTotalSize(qulonglong))); 0063 connect(m_mmsdownload, SIGNAL(signDownloaded(qulonglong)), this, SLOT(slotProcessedSizeAndPercent(qulonglong))); 0064 connect(m_mmsdownload, SIGNAL(signSpeed(ulong)), this, SLOT(slotSpeed(ulong))); 0065 connect(m_mmsdownload, SIGNAL(signRestartDownload(int)), this, SLOT(slotConnectionsErrors(int))); 0066 m_mmsdownload->start(); 0067 setTransferChange(Tc_Status, true); 0068 } 0069 0070 void MmsTransfer::stop() 0071 { 0072 /** The download is stopped, we call m_mmsdownload->stopTransfer() and when all threads 0073 * are finish m_mmsdownload will be deleted in MmsTransfer::slotResult(). 0074 */ 0075 if ((status() == Stopped) || (status() == Finished)) { 0076 return; 0077 } 0078 0079 if (m_mmsdownload) { 0080 if (m_mmsdownload->threadsAlive() > 0) { 0081 m_mmsdownload->stopTransfer(); 0082 } 0083 } 0084 0085 setStatus(Job::Stopped, i18nc("transfer state: stopped", "Stopped"), "process-stop"); 0086 m_downloadSpeed = 0; 0087 setTransferChange(Tc_Status | Tc_DownloadSpeed, true); 0088 } 0089 0090 void MmsTransfer::deinit(Transfer::DeleteOptions options) 0091 { 0092 /** Deleting the temporary file and the unfinish file*/ 0093 if (options & Transfer::DeleteFiles) { 0094 KIO::Job *del = KIO::del(QUrl::fromLocalFile(m_fileTemp), KIO::HideProgressInfo); 0095 if (!del->exec()) { 0096 qCDebug(KGET_DEBUG) << "Could not delete " << m_fileTemp; 0097 } 0098 del = KIO::del(m_dest, KIO::HideProgressInfo); 0099 if (!del->exec()) { 0100 qCDebug(KGET_DEBUG) << "Could not delete " << m_dest.path(); 0101 } 0102 } 0103 } 0104 0105 void MmsTransfer::slotResult() 0106 { 0107 /** This slot is connected with the signal finish of m_mmsdownload*/ 0108 /** Deleting m_mmsdownload.*/ 0109 m_mmsdownload->deleteLater(); 0110 m_mmsdownload = NULL; 0111 0112 /** If the download end without problems is changed the status to Finished and is deleted 0113 * the temporary file where is saved the status of all threads that download the file. 0114 */ 0115 if (m_downloadedSize == m_totalSize && m_totalSize != 0) { 0116 setStatus(Job::Finished, i18nc("Transfer State:Finished", "Finished"), "dialog-ok"); 0117 m_percent = 100; 0118 m_downloadSpeed = 0; 0119 setTransferChange(Tc_Status | Tc_Percent | Tc_DownloadSpeed, true); 0120 KIO::Job *del = KIO::del(QUrl::fromLocalFile(m_fileTemp), KIO::HideProgressInfo); 0121 if (!del->exec()) { 0122 qCDebug(KGET_DEBUG) << "Could not delete " << m_fileTemp; 0123 } 0124 } 0125 0126 /** If m_retryDownload == true then some threads has fail to connect, so the download was 0127 * stopped in MmsTransfer::slotConnectionsErrors() and here when all the connected thread 0128 * are finished we delete the temporary file and we start again the download using the amount 0129 * of threads defined in MmsTransfer::slotConnectionsErrors(). 0130 */ 0131 if (m_retryDownload) { 0132 m_retryDownload = false; 0133 KIO::Job *del = KIO::del(QUrl::fromLocalFile(m_fileTemp), KIO::HideProgressInfo); 0134 if (!del->exec()) { 0135 qCDebug(KGET_DEBUG) << "Could not delete " << m_fileTemp; 0136 } 0137 start(); 0138 } 0139 } 0140 0141 void MmsTransfer::slotTotalSize(qulonglong size) 0142 { 0143 m_totalSize = size; 0144 setTransferChange(Tc_TotalSize, true); 0145 } 0146 0147 void MmsTransfer::slotSpeed(ulong speed) 0148 { 0149 m_downloadSpeed = (status() == Running) ? speed : 0; 0150 setTransferChange(Tc_DownloadSpeed, true); 0151 } 0152 0153 void MmsTransfer::slotProcessedSizeAndPercent(qulonglong size) 0154 { 0155 m_downloadedSize = size; 0156 m_percent = (m_downloadedSize * 100) / m_totalSize; 0157 setTransferChange(Tc_DownloadedSize | Tc_Percent, true); 0158 } 0159 0160 void MmsTransfer::slotBrokenUrl() 0161 { 0162 setError(i18n("Download failed, could not access this URL."), "dialog-cancel", Job::NotSolveable); 0163 setTransferChange(Tc_Status, true); 0164 } 0165 0166 void MmsTransfer::slotNotAllowMultiDownload() 0167 { 0168 /** Some stream not allow seek in to a position, so we can't use more than one thread to 0169 * download the file, this is notify to the user because the download will take longer. 0170 */ 0171 KGet::showNotification(nullptr, 0172 "notification", 0173 i18n("This URL does not allow multiple connections,\n" 0174 "the download will take longer.")); 0175 } 0176 0177 void MmsTransfer::slotConnectionsErrors(int connections) 0178 { 0179 /** Here is called stop() for stop the download, set a new amount of thread 0180 * and set m_retryDownload = true for restart the download when mmsdownload is finish and 0181 * Q_EMIT a signal connected with MmsTransfer::slotResult(), see in MmsTransfer::slotResult() 0182 * for understand when its started again the download. 0183 */ 0184 stop(); 0185 m_retryDownload = true; 0186 if (connections) { 0187 m_amountThreads = connections; 0188 } else { 0189 m_amountThreads--; 0190 } 0191 } 0192 0193 #include "moc_mmstransfer.cpp"