File indexing completed on 2025-01-05 04:26:14
0001 /**************************************************************************************** 0002 * Copyright (c) 2007 Bart Cerneels <bart.cerneels@kde.org> * 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 0017 #ifndef SQLPODCASTPROVIDER_H 0018 #define SQLPODCASTPROVIDER_H 0019 0020 #include "core/podcasts/PodcastProvider.h" 0021 #include "core/podcasts/PodcastReader.h" 0022 #include "SqlPodcastMeta.h" 0023 0024 #include <QIcon> 0025 0026 #include <KLocalizedString> 0027 0028 class PodcastImageFetcher; 0029 0030 class QDialog; 0031 class QUrl; 0032 class PodcastReader; 0033 class QTimer; 0034 0035 namespace Ui { 0036 class SqlPodcastProviderSettingsWidget; 0037 } 0038 0039 namespace Podcasts { 0040 0041 /** 0042 @author Bart Cerneels <bart.cerneels@kde.org> 0043 */ 0044 class AMAROK_EXPORT SqlPodcastProvider : public Podcasts::PodcastProvider 0045 { 0046 Q_OBJECT 0047 public: 0048 SqlPodcastProvider(); 0049 ~SqlPodcastProvider() override; 0050 0051 //TrackProvider methods 0052 bool possiblyContainsTrack( const QUrl &url ) const override; 0053 Meta::TrackPtr trackForUrl( const QUrl &url ) override; 0054 0055 //PlaylistProvider methods 0056 QString prettyName() const override { return i18n("Local Podcasts"); } 0057 QIcon icon() const override { return QIcon::fromTheme( QStringLiteral("server-database") ); } 0058 0059 Playlists::PlaylistList playlists() override; 0060 0061 //PlaylistProvider methods 0062 QActionList providerActions() override; 0063 QActionList playlistActions( const Playlists::PlaylistList &playlists ) override; 0064 QActionList trackActions( const QMultiHash<Playlists::PlaylistPtr, int> &playlistTracks ) override; 0065 0066 //PodcastProvider methods 0067 Podcasts::PodcastEpisodePtr episodeForGuid( const QString &guid ) override; 0068 0069 void addPodcast( const QUrl &url ) override; 0070 0071 Podcasts::PodcastChannelPtr addChannel( const Podcasts::PodcastChannelPtr &channel ) override; 0072 Podcasts::PodcastEpisodePtr addEpisode( Podcasts::PodcastEpisodePtr episode ) override; 0073 0074 Podcasts::PodcastChannelList channels() override; 0075 0076 void completePodcastDownloads() override; 0077 0078 //SqlPodcastProvider specific methods 0079 virtual Podcasts::SqlPodcastChannelPtr podcastChannelForId( int podcastChannelDbId ); 0080 0081 virtual QUrl baseDownloadDir() const { return m_baseDownloadDir; } 0082 0083 public Q_SLOTS: 0084 void updateAll() override; 0085 void downloadEpisode( const Podcasts::PodcastEpisodePtr &episode ); 0086 void deleteDownloadedEpisode( const Podcasts::PodcastEpisodePtr &episode ); 0087 0088 void slotReadResult( PodcastReader *podcastReader ); 0089 void downloadEpisode( Podcasts::SqlPodcastEpisodePtr episode ); 0090 void deleteDownloadedEpisode( Podcasts::SqlPodcastEpisodePtr episode ); 0091 0092 private Q_SLOTS: 0093 void downloadResult( KJob * ); 0094 void addData( KIO::Job *job, const QByteArray & data ); 0095 void redirected( KIO::Job *, const QUrl& ); 0096 void autoUpdate(); 0097 void slotDeleteDownloadedEpisodes(); 0098 void slotDownloadEpisodes(); 0099 void slotSetKeep(); 0100 void slotConfigureChannel(); 0101 void slotRemoveChannels(); 0102 void slotUpdateChannels(); 0103 void slotDownloadProgress( KJob *job, unsigned long percent ); 0104 void slotWriteTagsToFiles(); 0105 void slotConfigChanged(); 0106 void slotExportOpml(); 0107 0108 Q_SIGNALS: 0109 void totalPodcastDownloadProgress( int progress ); 0110 0111 //SqlPodcastProvider signals 0112 void episodeDownloaded( Podcasts::PodcastEpisodePtr ); 0113 void episodeDeleted( Podcasts::PodcastEpisodePtr ); 0114 0115 private Q_SLOTS: 0116 void channelImageReady( Podcasts::PodcastChannelPtr, const QImage &); 0117 void podcastImageFetcherDone( PodcastImageFetcher * ); 0118 void slotConfigureProvider(); 0119 0120 void slotStatusBarNewProgressOperation( KIO::TransferJob * job, 0121 const QString &description, 0122 Podcasts::PodcastReader* reader ); 0123 void slotStatusBarErrorMessage( const QString &message ); 0124 void slotOpmlWriterDone( int result ); 0125 0126 private: 0127 void startTimer(); 0128 void configureProvider(); 0129 void configureChannel( Podcasts::SqlPodcastChannelPtr channel ); 0130 void updateSqlChannel( Podcasts::SqlPodcastChannelPtr channel ); 0131 0132 /** creates all the necessary tables, indexes etc. for the database */ 0133 void createTables() const; 0134 void loadPodcasts(); 0135 0136 /** @arg string: a url, localUrl or guid in string form */ 0137 Podcasts::SqlPodcastEpisodePtr sqlEpisodeForString( const QString &string ); 0138 0139 void updateDatabase( int fromVersion, int toVersion ); 0140 void fetchImage( const Podcasts::SqlPodcastChannelPtr &channel ); 0141 0142 /** shows a modal dialog asking the user if he really wants to unsubscribe 0143 and if he wants to keep the podcast media */ 0144 QPair<bool, bool> confirmUnsubscribe( Podcasts::SqlPodcastChannelPtr channel ); 0145 0146 /** remove the episodes in the list from the filesystem */ 0147 void deleteDownloadedEpisodes( Podcasts::SqlPodcastEpisodeList &episodes ); 0148 0149 void moveDownloadedEpisodes( Podcasts::SqlPodcastChannelPtr channel ); 0150 0151 /** Removes a podcast from the list. Will ask for confirmation to delete the episodes 0152 * as well 0153 */ 0154 void removeSubscription( Podcasts::SqlPodcastChannelPtr channel ); 0155 0156 void subscribe( const QUrl &url ); 0157 QFile* createTmpFile ( Podcasts::SqlPodcastEpisodePtr sqlEpisode ); 0158 void cleanupDownload( KJob *job, bool downloadFailed ); 0159 0160 /** returns true if the file that is downloaded by 'job' is already locally available */ 0161 bool checkEnclosureLocallyAvailable( KIO::Job *job ); 0162 0163 Podcasts::SqlPodcastChannelList m_channels; 0164 0165 QTimer *m_updateTimer; 0166 int m_autoUpdateInterval; //interval between autoupdate attempts in minutes 0167 unsigned int m_updatingChannels; 0168 unsigned int m_maxConcurrentUpdates; 0169 Podcasts::SqlPodcastChannelList m_updateQueue; 0170 QList<QUrl> m_subscribeQueue; 0171 0172 struct PodcastEpisodeDownload { 0173 Podcasts::SqlPodcastEpisodePtr episode; 0174 QFile *tmpFile; 0175 QString fileName; 0176 bool finalNameReady; 0177 }; 0178 0179 QHash<KJob *, struct PodcastEpisodeDownload> m_downloadJobMap; 0180 0181 Podcasts::SqlPodcastEpisodeList m_downloadQueue; 0182 int m_maxConcurrentDownloads; 0183 int m_completedDownloads; 0184 0185 QUrl m_baseDownloadDir; 0186 0187 QDialog *m_providerSettingsDialog; 0188 Ui::SqlPodcastProviderSettingsWidget *m_providerSettingsWidget; 0189 0190 QList<QAction *> m_providerActions; 0191 0192 QAction *m_configureChannelAction; //Configure a Channel 0193 QAction *m_deleteAction; //delete a downloaded Episode 0194 QAction *m_downloadAction; 0195 QAction *m_keepAction; 0196 QAction *m_removeAction; //remove a subscription 0197 QAction *m_updateAction; 0198 QAction *m_writeTagsAction; //write feed information to downloaded file 0199 0200 PodcastImageFetcher *m_podcastImageFetcher; 0201 }; 0202 0203 } //namespace Podcasts 0204 0205 #endif