1 /**************************************************************************************** 2 * Copyright (c) 2007 Bart Cerneels <bart.cerneels@kde.org> * 3 * * 4 * This program is free software; you can redistribute it and/or modify it under * 5 * the terms of the GNU General Public License as published by the Free Software * 6 * Foundation; either version 2 of the License, or (at your option) any later * 7 * version. * 8 * * 9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 11 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 12 * * 13 * You should have received a copy of the GNU General Public License along with * 14 * this program. If not, see <http://www.gnu.org/licenses/>. * 15 ****************************************************************************************/ 16 17 #ifndef SQLPODCASTPROVIDER_H 18 #define SQLPODCASTPROVIDER_H 19 20 #include "core/podcasts/PodcastProvider.h" 21 #include "core/podcasts/PodcastReader.h" 22 #include "SqlPodcastMeta.h" 23 24 #include <QIcon> 25 26 #include <KLocalizedString> 27 28 class PodcastImageFetcher; 29 30 class QDialog; 31 class QUrl; 32 class PodcastReader; 33 class QTimer; 34 35 namespace Ui { 36 class SqlPodcastProviderSettingsWidget; 37 } 38 39 namespace Podcasts { 40 41 /** 42 @author Bart Cerneels <bart.cerneels@kde.org> 43 */ 44 class AMAROK_EXPORT SqlPodcastProvider : public Podcasts::PodcastProvider 45 { 46 Q_OBJECT 47 public: 48 SqlPodcastProvider(); 49 ~SqlPodcastProvider() override; 50 51 //TrackProvider methods 52 bool possiblyContainsTrack( const QUrl &url ) const override; 53 Meta::TrackPtr trackForUrl( const QUrl &url ) override; 54 55 //PlaylistProvider methods prettyName()56 QString prettyName() const override { return i18n("Local Podcasts"); } icon()57 QIcon icon() const override { return QIcon::fromTheme( QStringLiteral("server-database") ); } 58 59 Playlists::PlaylistList playlists() override; 60 61 //PlaylistProvider methods 62 QActionList providerActions() override; 63 QActionList playlistActions( const Playlists::PlaylistList &playlists ) override; 64 QActionList trackActions( const QMultiHash<Playlists::PlaylistPtr, int> &playlistTracks ) override; 65 66 //PodcastProvider methods 67 Podcasts::PodcastEpisodePtr episodeForGuid( const QString &guid ) override; 68 69 void addPodcast( const QUrl &url ) override; 70 71 Podcasts::PodcastChannelPtr addChannel( const Podcasts::PodcastChannelPtr &channel ) override; 72 Podcasts::PodcastEpisodePtr addEpisode( Podcasts::PodcastEpisodePtr episode ) override; 73 74 Podcasts::PodcastChannelList channels() override; 75 76 void completePodcastDownloads() override; 77 78 //SqlPodcastProvider specific methods 79 virtual Podcasts::SqlPodcastChannelPtr podcastChannelForId( int podcastChannelDbId ); 80 baseDownloadDir()81 virtual QUrl baseDownloadDir() const { return m_baseDownloadDir; } 82 83 public Q_SLOTS: 84 void updateAll() override; 85 void downloadEpisode( const Podcasts::PodcastEpisodePtr &episode ); 86 void deleteDownloadedEpisode( const Podcasts::PodcastEpisodePtr &episode ); 87 88 void slotReadResult( PodcastReader *podcastReader ); 89 void downloadEpisode( Podcasts::SqlPodcastEpisodePtr episode ); 90 void deleteDownloadedEpisode( Podcasts::SqlPodcastEpisodePtr episode ); 91 92 private Q_SLOTS: 93 void downloadResult( KJob * ); 94 void addData( KIO::Job *job, const QByteArray & data ); 95 void redirected( KIO::Job *, const QUrl& ); 96 void autoUpdate(); 97 void slotDeleteDownloadedEpisodes(); 98 void slotDownloadEpisodes(); 99 void slotSetKeep(); 100 void slotConfigureChannel(); 101 void slotRemoveChannels(); 102 void slotUpdateChannels(); 103 void slotDownloadProgress( KJob *job, unsigned long percent ); 104 void slotWriteTagsToFiles(); 105 void slotConfigChanged(); 106 void slotExportOpml(); 107 108 Q_SIGNALS: 109 void totalPodcastDownloadProgress( int progress ); 110 111 //SqlPodcastProvider signals 112 void episodeDownloaded( Podcasts::PodcastEpisodePtr ); 113 void episodeDeleted( Podcasts::PodcastEpisodePtr ); 114 115 private Q_SLOTS: 116 void channelImageReady( Podcasts::PodcastChannelPtr, const QImage &); 117 void podcastImageFetcherDone( PodcastImageFetcher * ); 118 void slotConfigureProvider(); 119 120 void slotStatusBarNewProgressOperation( KIO::TransferJob * job, 121 const QString &description, 122 Podcasts::PodcastReader* reader ); 123 void slotStatusBarSorryMessage( const QString &message ); 124 void slotOpmlWriterDone( int result ); 125 126 private: 127 void startTimer(); 128 void configureProvider(); 129 void configureChannel( Podcasts::SqlPodcastChannelPtr channel ); 130 void updateSqlChannel( Podcasts::SqlPodcastChannelPtr channel ); 131 132 /** creates all the necessary tables, indexes etc. for the database */ 133 void createTables() const; 134 void loadPodcasts(); 135 136 /** @arg string: a url, localUrl or guid in string form */ 137 Podcasts::SqlPodcastEpisodePtr sqlEpisodeForString( const QString &string ); 138 139 void updateDatabase( int fromVersion, int toVersion ); 140 void fetchImage( const Podcasts::SqlPodcastChannelPtr &channel ); 141 142 /** shows a modal dialog asking the user if he really wants to unsubscribe 143 and if he wants to keep the podcast media */ 144 QPair<bool, bool> confirmUnsubscribe( Podcasts::SqlPodcastChannelPtr channel ); 145 146 /** remove the episodes in the list from the filesystem */ 147 void deleteDownloadedEpisodes( Podcasts::SqlPodcastEpisodeList &episodes ); 148 149 void moveDownloadedEpisodes( Podcasts::SqlPodcastChannelPtr channel ); 150 151 /** Removes a podcast from the list. Will ask for confirmation to delete the episodes 152 * as well 153 */ 154 void removeSubscription( Podcasts::SqlPodcastChannelPtr channel ); 155 156 void subscribe( const QUrl &url ); 157 QFile* createTmpFile ( Podcasts::SqlPodcastEpisodePtr sqlEpisode ); 158 void cleanupDownload( KJob *job, bool downloadFailed ); 159 160 /** returns true if the file that is downloaded by 'job' is already locally available */ 161 bool checkEnclosureLocallyAvailable( KIO::Job *job ); 162 163 Podcasts::SqlPodcastChannelList m_channels; 164 165 QTimer *m_updateTimer; 166 int m_autoUpdateInterval; //interval between autoupdate attempts in minutes 167 unsigned int m_updatingChannels; 168 unsigned int m_maxConcurrentUpdates; 169 Podcasts::SqlPodcastChannelList m_updateQueue; 170 QList<QUrl> m_subscribeQueue; 171 172 struct PodcastEpisodeDownload { 173 Podcasts::SqlPodcastEpisodePtr episode; 174 QFile *tmpFile; 175 QString fileName; 176 bool finalNameReady; 177 }; 178 179 QHash<KJob *, struct PodcastEpisodeDownload> m_downloadJobMap; 180 181 Podcasts::SqlPodcastEpisodeList m_downloadQueue; 182 int m_maxConcurrentDownloads; 183 int m_completedDownloads; 184 185 QUrl m_baseDownloadDir; 186 187 QDialog *m_providerSettingsDialog; 188 Ui::SqlPodcastProviderSettingsWidget *m_providerSettingsWidget; 189 190 QList<QAction *> m_providerActions; 191 192 QAction *m_configureChannelAction; //Configure a Channel 193 QAction *m_deleteAction; //delete a downloaded Episode 194 QAction *m_downloadAction; 195 QAction *m_keepAction; 196 QAction *m_removeAction; //remove a subscription 197 QAction *m_updateAction; 198 QAction *m_writeTagsAction; //write feed information to downloaded file 199 200 PodcastImageFetcher *m_podcastImageFetcher; 201 }; 202 203 } //namespace Podcasts 204 205 #endif 206