File indexing completed on 2024-05-19 04:49:24
0001 /**************************************************************************************** 0002 * Copyright (c) 2013 Tatjana Gornak <t.gornak@gmail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. If not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 #include "core-impl/playlists/types/file/PlaylistFileLoaderJob.h" 0017 0018 #include "core/meta/Meta.h" 0019 #include "core/playlists/PlaylistFormat.h" 0020 #include "core/logger/Logger.h" 0021 #include "core/support/Amarok.h" 0022 #include "core/support/Components.h" 0023 #include "core/support/Debug.h" 0024 #include "core/support/SemaphoreReleaser.h" 0025 0026 #include <KLocalizedString> 0027 #include <KMessageBox> 0028 #include <KIO/Job> 0029 0030 #include <QFile> 0031 #include <QFileInfo> 0032 #include <QString> 0033 #include <QTextStream> 0034 #include <QUrl> 0035 0036 using namespace Playlists; 0037 0038 PlaylistFileLoaderJob::PlaylistFileLoaderJob( const PlaylistFilePtr &playlist ) 0039 : QObject() 0040 , m_playlist( playlist ) 0041 { 0042 connect( this, &PlaylistFileLoaderJob::done, this, &PlaylistFileLoaderJob::slotDone ); 0043 0044 // we must handle remove downloading here as KIO is coupled with GUI as is not 0045 // designed to work from another thread 0046 QUrl url( playlist->uidUrl() ); 0047 // KIO::file_copy in KF5 needs scheme 0048 if (url.isRelative() && url.host().isEmpty()) { 0049 url.setScheme("file"); 0050 } 0051 if( url.isLocalFile() ) 0052 { 0053 m_actualPlaylistFile = url.toLocalFile(); 0054 m_downloadSemaphore.release(); // pretend file "already downloaded" 0055 } 0056 else 0057 { 0058 // m_tempFile.setFileTemplate( QDir::tempPath() + "/XXXXXX." + Amarok::extension( url.url() ) ); 0059 if( !m_tempFile.open() ) 0060 { 0061 Amarok::Logger::longMessage( 0062 i18n( "Could not create a temporary file to download playlist." ) ); 0063 m_downloadSemaphore.release(); // prevent deadlock 0064 return; 0065 } 0066 0067 KIO::FileCopyJob *job = KIO::file_copy( url , QUrl::fromLocalFile(m_tempFile.fileName()), 0774, 0068 KIO::Overwrite | KIO::HideProgressInfo ); 0069 Amarok::Logger::newProgressOperation( job, 0070 i18n("Downloading remote playlist" ) ); 0071 if( playlist->isLoadingAsync() ) 0072 // job is started automatically by KIO 0073 connect( job, &KIO::FileCopyJob::finished, this, &PlaylistFileLoaderJob::slotDonwloadFinished ); 0074 else 0075 { 0076 job->exec(); 0077 slotDonwloadFinished( job ); 0078 } 0079 } 0080 } 0081 0082 void 0083 PlaylistFileLoaderJob::run(ThreadWeaver::JobPointer self, ThreadWeaver::Thread *thread) 0084 { 0085 Q_UNUSED(self); 0086 Q_UNUSED(thread); 0087 SemaphoreReleaser releaser( m_playlist->isLoadingAsync() ? nullptr : &m_playlist->m_loadingDone ); 0088 m_downloadSemaphore.acquire(); // wait for possible download to finish 0089 if( m_actualPlaylistFile.isEmpty() ) 0090 return; // previous error, already reported 0091 0092 QFile file( m_actualPlaylistFile ); 0093 if( !file.open( QIODevice::ReadOnly | QIODevice::Text ) ) 0094 { 0095 Amarok::Logger::longMessage( i18nc( "%1 is file path", 0096 "Cannot read playlist from %1", m_actualPlaylistFile ), Amarok::Logger::Error ); 0097 return; 0098 } 0099 0100 QByteArray content = file.readAll(); 0101 file.close(); 0102 0103 m_playlist->load( content ); 0104 } 0105 0106 void 0107 PlaylistFileLoaderJob::defaultBegin(const ThreadWeaver::JobPointer& self, ThreadWeaver::Thread *thread) 0108 { 0109 Q_EMIT started(self); 0110 ThreadWeaver::Job::defaultBegin(self, thread); 0111 } 0112 0113 void 0114 PlaylistFileLoaderJob::defaultEnd(const ThreadWeaver::JobPointer& self, ThreadWeaver::Thread *thread) 0115 { 0116 ThreadWeaver::Job::defaultEnd(self, thread); 0117 if (!self->success()) { 0118 Q_EMIT failed(self); 0119 } 0120 Q_EMIT done(self); 0121 } 0122 0123 void 0124 PlaylistFileLoaderJob::slotDonwloadFinished( KJob *job ) 0125 { 0126 if( job->error() ) 0127 { 0128 using namespace Amarok; 0129 warning() << job->errorString(); 0130 } 0131 else 0132 m_actualPlaylistFile = m_tempFile.fileName(); 0133 m_downloadSemaphore.release(); 0134 } 0135 0136 void 0137 PlaylistFileLoaderJob::slotDone() 0138 { 0139 m_playlist->notifyObserversTracksLoaded(); 0140 deleteLater(); 0141 }