1 /****************************************************************************************
2  * Copyright (c) 2010 - 2011 Stefan Derkits <stefan@derkits.at>                         *
3  * Copyright (c) 2010 - 2011 Christian Wagner <christian.wagner86@gmx.at>               *
4  * Copyright (c) 2010 - 2011 Felix Winter <ixos01@gmail.com>                            *
5  *                                                                                      *
6  * This program is free software; you can redistribute it and/or modify it under        *
7  * the terms of the GNU General Public License as published by the Free Software        *
8  * Foundation; either version 2 of the License, or (at your option) any later           *
9  * version.                                                                             *
10  *                                                                                      *
11  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
13  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
14  *                                                                                      *
15  * You should have received a copy of the GNU General Public License along with         *
16  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
17  ****************************************************************************************/
18 
19 #define DEBUG_PREFIX "GpodderService"
20 
21 #include "GpodderService.h"
22 
23 #include "core/podcasts/PodcastProvider.h"
24 #include "core/support/Debug.h"
25 #include "GpodderPodcastTreeItem.h"
26 #include "GpodderServiceConfig.h"
27 #include "GpodderServiceModel.h"
28 #include "GpodderServiceView.h"
29 #include "GpodderSortFilterProxyModel.h"
30 #include <mygpo-qt5/ApiRequest.h>
31 #include <mygpo-qt5/Podcast.h>
32 #include "playlistmanager/PlaylistManager.h"
33 #include "widgets/SearchWidget.h"
34 
35 #include <QHostInfo>
36 #include <QStandardPaths>
37 #include <QUrl>
38 
39 
GpodderServiceFactory()40 GpodderServiceFactory::GpodderServiceFactory()
41     : ServiceFactory()
42 {}
43 
~GpodderServiceFactory()44 GpodderServiceFactory::~GpodderServiceFactory()
45 {}
46 
47 void
init()48 GpodderServiceFactory::init()
49 {
50     ServiceBase *service = createGpodderService();
51     if( service )
52     {
53         m_initialized = true;
54         emit newService( service );
55     }
56 }
57 
58 QString
name()59 GpodderServiceFactory::name()
60 {
61     return QStringLiteral("gpodder.net");
62 }
63 
64 KConfigGroup
config()65 GpodderServiceFactory::config()
66 {
67     return Amarok::config( GpodderServiceConfig::configSectionName() );
68 }
69 
70 void
slotCreateGpodderService()71 GpodderServiceFactory::slotCreateGpodderService()
72 {
73     //Until we can remove a service when networking gets disabled, only create it the first time.
74     if( !m_initialized )
75     {
76         ServiceBase *service = createGpodderService();
77         if( service )
78         {
79             m_initialized = true;
80             emit newService( service );
81         }
82     }
83 }
84 
85 void
slotRemoveGpodderService()86 GpodderServiceFactory::slotRemoveGpodderService()
87 {
88     if( activeServices().isEmpty() )
89         return;
90 
91     m_initialized = false;
92     emit removeService( activeServices().first() );
93 }
94 
95 ServiceBase *
createGpodderService()96 GpodderServiceFactory::createGpodderService()
97 {
98     ServiceBase *service = new GpodderService( this, QLatin1String( "gpodder" ) );
99     return service;
100 }
101 
GpodderService(GpodderServiceFactory * parent,const QString & name)102 GpodderService::GpodderService( GpodderServiceFactory *parent, const QString &name )
103     : ServiceBase( name, parent, false )
104     , m_inited( false )
105     , m_apiRequest( nullptr )
106     , m_podcastProvider( nullptr )
107     , m_proxyModel( nullptr )
108     , m_subscribeButton( nullptr )
109     , m_selectionModel( nullptr )
110 {
111     DEBUG_BLOCK
112 
113     setShortDescription( i18n( "gpodder.net: Podcast Directory Service" ) );
114     setIcon( QIcon::fromTheme( QStringLiteral("view-services-gpodder-amarok") ) );
115     setLongDescription(
116                 i18n( "gpodder.net is an online Podcast Directory & Synchonisation Service." ) );
117     setImagePath( QStandardPaths::locate( QStandardPaths::GenericDataLocation, QStringLiteral("amarok/images/mygpo.png") ) );
118 
119     init();
120 }
121 
~GpodderService()122 GpodderService::~GpodderService()
123 {
124     DEBUG_BLOCK
125 
126     if( m_podcastProvider )
127     {
128         //Remove the provider
129         The::playlistManager()->removeProvider( m_podcastProvider );
130         delete m_podcastProvider;
131     }
132 
133     if ( m_apiRequest )
134         delete m_apiRequest;
135 }
136 
137 //This Method should only contain the most necessary things for initilazing the Service
138 void
init()139 GpodderService::init()
140 {
141     DEBUG_BLOCK
142 
143     GpodderServiceConfig config;
144 
145     const QString &username = config.username();
146     const QString &password = config.password();
147 
148     if ( m_apiRequest )
149         delete m_apiRequest;
150 
151     //We have to check this here too, since KWallet::openWallet() doesn't
152     //guarantee that it will always return a wallet.
153     //Notice that LastFm service does the same verification.
154     if ( !config.isDataLoaded() )
155     {
156         debug() << "Failed to read gpodder credentials.";
157         m_apiRequest = new mygpo::ApiRequest( The::networkAccessManager() );
158     }
159     else
160     {
161         if( config.enableProvider() )
162         {
163             m_apiRequest = new mygpo::ApiRequest( username,
164                                                   password,
165                                                   The::networkAccessManager() );
166             if( m_podcastProvider )
167                 delete m_podcastProvider;
168 
169             enableGpodderProvider( username );
170         }
171         else
172             m_apiRequest = new mygpo::ApiRequest( The::networkAccessManager() );
173     }
174 
175     setServiceReady( true );
176     m_inited = true;
177 }
178 
179 //This Method should contain the rest of the Service Initialization (not soo necessary things, that
180 //can be done after the Object was created)
181 void
polish()182 GpodderService::polish()
183 {
184     DEBUG_BLOCK
185 
186     generateWidgetInfo();
187 
188     if( m_polished )
189         return;
190 
191     //do not allow this content to get added to the playlist. At least not for now
192     setPlayableTracks( false );
193 
194     GpodderServiceView *view = new GpodderServiceView( this );
195     view->setHeaderHidden( true );
196     view->setFrameShape( QFrame::NoFrame );
197 
198     // Was set true in OpmlDirectoryService, but I think we won't need this on true
199     view->setDragEnabled( false );
200     view->setItemsExpandable( true );
201 
202     view->setSortingEnabled( false );
203     view->setEditTriggers( QAbstractItemView::NoEditTriggers );
204     view->setDragDropMode( QAbstractItemView::NoDragDrop );
205 
206     setView( view );
207 
208     GpodderServiceModel *sourceModel = new GpodderServiceModel( m_apiRequest, this );
209 
210     m_proxyModel = new GpodderSortFilterProxyModel( this );
211     m_proxyModel->setDynamicSortFilter( true );
212     m_proxyModel->setFilterCaseSensitivity( Qt::CaseInsensitive );
213 
214     m_proxyModel->setSourceModel( sourceModel );
215 
216     setModel( m_proxyModel );
217 
218     m_selectionModel = view->selectionModel();
219 
220     m_subscribeButton = new QPushButton();
221     m_subscribeButton->setParent( m_bottomPanel );
222     m_subscribeButton->setText( i18n( "Subscribe" ) );
223     m_subscribeButton->setObjectName( "subscribeButton" );
224     m_subscribeButton->setIcon( QIcon::fromTheme( QStringLiteral("get-hot-new-stuff-amarok") ) );
225 
226     m_subscribeButton->setEnabled( true );
227 
228     connect( m_subscribeButton, &QPushButton::clicked, this, &GpodderService::subscribe );
229 
230     connect( m_searchWidget, &SearchWidget::filterChanged,
231              m_proxyModel, &QSortFilterProxyModel::setFilterWildcard );
232 
233     m_polished = true;
234 }
235 
236 void
itemSelected(CollectionTreeItem * selectedItem)237 GpodderService::itemSelected( CollectionTreeItem * selectedItem )
238 {
239     Q_UNUSED( selectedItem )
240     DEBUG_BLOCK
241     return;
242 }
243 
244 void
subscribe()245 GpodderService::subscribe()
246 {
247     QModelIndex index = m_proxyModel->mapToSource( m_selectionModel->currentIndex() );
248     GpodderTreeItem *treeItem = static_cast<GpodderTreeItem*>( index.internalPointer() );
249 
250     if( GpodderPodcastTreeItem *podcastTreeItem = qobject_cast<GpodderPodcastTreeItem*>( treeItem ) )
251     {
252         Podcasts::PodcastProvider *podcastProvider = The::playlistManager()->defaultPodcasts();
253         QUrl kUrl( podcastTreeItem->podcast()->url() );
254         podcastProvider->addPodcast( kUrl );
255     }
256 }
257 
258 void
enableGpodderProvider(const QString & username)259 GpodderService::enableGpodderProvider( const QString &username )
260 {
261     DEBUG_BLOCK
262 
263     QString deviceName = QLatin1String( "amarok-" ) % QHostInfo::localHostName();
264 
265     debug() << QString( "Enabling GpodderProvider( Username: %1 - Device: %1 )" )
266                         .arg( username )
267                         .arg( deviceName );
268 
269     m_podcastProvider = new Podcasts::GpodderProvider( username, deviceName, m_apiRequest );
270 
271     //Add the gpodder's provider to the playlist manager
272     The::playlistManager()->addProvider( m_podcastProvider, PlaylistManager::PodcastChannel );
273 
274 }
275