File indexing completed on 2024-05-19 04:50:12

0001 /****************************************************************************************
0002  * Copyright (c) 2011 Stefan Derkits <stefan@derkits.at>                                *
0003  * Copyright (c) 2011 Christian Wagner <christian.wagner86@gmx.at>                      *
0004  * Copyright (c) 2011 Felix Winter <ixos01@gmail.com>                                   *
0005  * Copyright (c) 2011 Lucas Lira Gomes <x8lucas8x@gmail.com>                            *
0006  *                                                                                      *
0007  * This program is free software; you can redistribute it and/or modify it under        *
0008  * the terms of the GNU General Public License as published by the Free Software        *
0009  * Foundation; either version 2 of the License, or (at your option) any later           *
0010  * version.                                                                             *
0011  *                                                                                      *
0012  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0013  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0014  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0015  *                                                                                      *
0016  * You should have received a copy of the GNU General Public License along with         *
0017  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0018  ****************************************************************************************/
0019 
0020 #ifndef GPODDERPROVIDER_H
0021 #define GPODDERPROVIDER_H
0022 
0023 #include "core/podcasts/PodcastProvider.h"
0024 #include "core/podcasts/PodcastReader.h"
0025 #include "GpodderPodcastMeta.h"
0026 #include <mygpo-qt5/ApiRequest.h>
0027 #include <mygpo-qt5/EpisodeActionList.h>
0028 #include "playlistmanager/file/KConfigSyncRelStore.h"
0029 #include "playlistmanager/PlaylistManager.h"
0030 
0031 #include <QDialog>
0032 #include <KIO/Job>
0033 
0034 #include <QCheckBox>
0035 #include <QPair>
0036 #include <QQueue>
0037 
0038 using namespace mygpo;
0039 
0040 class QAction;
0041 
0042 namespace Podcasts
0043 {
0044 class GpodderProvider : public PodcastProvider
0045 {
0046     Q_OBJECT
0047 public:
0048     GpodderProvider( const QString& username, const QString& devicename, ApiRequest *apiRequest );
0049     ~GpodderProvider() override;
0050 
0051     //TrackProvider methods
0052     bool possiblyContainsTrack( const QUrl &url ) const override;
0053     Meta::TrackPtr trackForUrl( const QUrl &url ) override;
0054 
0055     //PodcastProvider methods
0056     /** Special function to get an episode for a given guid.
0057      *
0058      * note: this functions is required because QUrl does not preserve every possible guids.
0059      * This means we can not use trackForUrl().
0060      * Problematic guids contain non-latin characters, percent encoded parts, capitals, etc.
0061      */
0062     PodcastEpisodePtr episodeForGuid( const QString &guid ) override;
0063 
0064     void addPodcast( const QUrl &url ) override;
0065 
0066     Podcasts::PodcastChannelPtr addChannel( const Podcasts::PodcastChannelPtr &channel ) override;
0067     Podcasts::PodcastEpisodePtr addEpisode( Podcasts::PodcastEpisodePtr episode ) override;
0068 
0069     Podcasts::PodcastChannelList channels() override;
0070 
0071     // PlaylistProvider methods
0072     QString prettyName() const override;
0073     QIcon icon() const override;
0074     Playlists::PlaylistList playlists() override;
0075     void completePodcastDownloads() override;
0076 
0077     /** Copy a playlist to the provider.
0078     */
0079     Playlists::PlaylistPtr addPlaylist( Playlists::PlaylistPtr playlist ) override;
0080     QActionList playlistActions( const Playlists::PlaylistList &playlists ) override;
0081 
0082 private Q_SLOTS:
0083     void requestDeviceUpdates();
0084     void deviceUpdatesFinished();
0085     void continueDeviceUpdatesFinished();
0086     void deviceUpdatesParseError();
0087     void deviceUpdatesRequestError( QNetworkReply::NetworkError error );
0088 
0089     void requestEpisodeActionsInCascade();
0090     void episodeActionsInCascadeFinished();
0091     void episodeActionsInCascadeParseError();
0092     void episodeActionsInCascadeRequestError( QNetworkReply::NetworkError error );
0093 
0094     void timerGenerateEpisodeAction();
0095     void timerSynchronizeStatus();
0096     void timerSynchronizeSubscriptions();
0097     void timerPrepareToSyncPodcastStatus();
0098 
0099     void slotRemoveChannels();
0100     void synchronizeStatusParseError();
0101     void synchronizeStatusRequestError( QNetworkReply::NetworkError error );
0102     void slotSuccessfulStatusSynchronisation();
0103     void slotSuccessfulSubscriptionSynchronisation();
0104 
0105     void slotSyncPlaylistAdded( Playlists::PlaylistPtr playlist );
0106     void slotSyncPlaylistRemoved( Playlists::PlaylistPtr playlist );
0107 
0108     void slotPaused();
0109     void slotTrackChanged( Meta::TrackPtr track );
0110     void slotTrackPositionChanged( qint64 position, bool userSeek );
0111 
0112     void requestUrlResolve( GpodderPodcastChannelPtr channel );
0113     void urlResolvePermanentRedirection ( KIO::Job *job, const QUrl &fromUrl,
0114             const QUrl &toUrl );
0115     void urlResolveFinished( KJob * );
0116 
0117     void slotEpisodeDownloaded( Podcasts::PodcastEpisodePtr episode );
0118     void slotEpisodeDeleted( Podcasts::PodcastEpisodePtr episode );
0119     void slotEpisodeMarkedAsNew( Podcasts::PodcastEpisodePtr episode );
0120 
0121 private:
0122     QActionList channelActions( PodcastChannelList episodes );
0123 
0124     ApiRequest *m_apiRequest;
0125     const QString m_username;
0126     const QString m_deviceName;
0127     PodcastChannelList m_channels;
0128     KIO::TransferJob *m_resolveUrlJob;
0129 
0130     AddRemoveResultPtr m_addRemoveResult;
0131     DeviceUpdatesPtr m_deviceUpdatesResult;
0132     AddRemoveResultPtr m_episodeActionsResult;
0133     EpisodeActionListPtr m_episodeActionListResult;
0134 
0135     qulonglong m_timestampStatus;
0136     qulonglong m_timestampSubscription;
0137 
0138     qulonglong subscriptionTimestamp();
0139     void setSubscriptionTimestamp( qulonglong newTimestamp );
0140 
0141     void removeChannel( const QUrl &url );
0142     void createPlayStatusBookmark();
0143 
0144     void synchronizeStatus();
0145     void synchronizeSubscriptions();
0146     void updateLocalPodcasts( const QList< QPair<QUrl,QUrl> > updatedUrls );
0147 
0148     KConfigGroup gpodderActionsConfig() const;
0149     void loadCachedEpisodeActions();
0150     void saveCachedEpisodeActions();
0151 
0152     KConfigGroup gpodderPodcastsConfig() const;
0153     void loadCachedPodcastsChanges();
0154     void saveCachedPodcastsChanges();
0155 
0156     QAction *m_removeAction;
0157 
0158     //Lists of podcasts to be added or removed from gpodder.net
0159     QList<QUrl> m_addList;
0160     QList<QUrl> m_removeList;
0161 
0162     QUrl resolvedPodcastUrl( const PodcastEpisodePtr episode );
0163 
0164     QMap<QUrl,QUrl> m_redirectionUrlMap;
0165     QQueue<QUrl> m_channelsToRequestActions;
0166     QMap<KIO::TransferJob *,GpodderPodcastChannelPtr> m_resolvedPodcasts;
0167     //Used as a temporary container for podcasts with already urls resolved
0168     //before adding them to m_channels
0169     QQueue<GpodderPodcastChannelPtr> m_resolvedChannelsToBeAdded;
0170 
0171     QMap<QUrl,EpisodeActionPtr> m_episodeStatusMap;
0172     QMap<QUrl,EpisodeActionPtr> m_uploadEpisodeStatusMap;
0173 
0174     QTimer *m_timerGeneratePlayAction;
0175     QTimer *m_timerSynchronizeStatus;
0176     QTimer *m_timerSynchronizeSubscriptions;
0177 
0178     Meta::TrackPtr m_trackToSyncStatus;
0179 };
0180 
0181 }
0182 
0183 #endif