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

0001 /****************************************************************************************
0002  * Copyright (c) 2007 Nikolaj Hald Nielsen <nhn@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 #include "AmpacheServiceCollection.h"
0018 
0019 #include "AmpacheServiceQueryMaker.h"
0020 #include "NetworkAccessManagerProxy.h"
0021 
0022 #include <KLocalizedString>
0023 #include <ThreadWeaver/ThreadWeaver>
0024 #include <ThreadWeaver/Queue>
0025 
0026 #include <QDomDocument>
0027 #include <QNetworkReply>
0028 #include <QUrlQuery>
0029 
0030 using namespace Collections;
0031 
0032 AmpacheServiceCollection::AmpacheServiceCollection( ServiceBase *service,
0033                                                     const QUrl &server,
0034                                                     const QString &sessionId )
0035     : ServiceCollection( service, "AmpacheCollection", "AmpacheCollection" )
0036     , m_server( server )
0037     , m_sessionId( sessionId )
0038 {
0039     m_trackForUrlWorker = nullptr;
0040 }
0041 
0042 AmpacheServiceCollection::~AmpacheServiceCollection()
0043 {
0044 }
0045 
0046 QueryMaker *
0047 AmpacheServiceCollection::queryMaker()
0048 {
0049     return new AmpacheServiceQueryMaker( this, m_server, m_sessionId );
0050 }
0051 
0052 QString
0053 AmpacheServiceCollection::collectionId() const
0054 {
0055     return "Ampache: " + m_server.url();
0056 }
0057 
0058 QString
0059 AmpacheServiceCollection::prettyName() const
0060 {
0061     return i18n( "Ampache Server %1", m_server.url() );
0062 }
0063 
0064 bool
0065 AmpacheServiceCollection::possiblyContainsTrack( const QUrl &url ) const
0066 {
0067     return m_server.isParentOf( url );
0068 }
0069 
0070 void
0071 AmpacheServiceCollection::slotAuthenticationNeeded()
0072 {
0073     Q_EMIT authenticationNeeded();
0074 }
0075 
0076 Meta::TrackPtr
0077 AmpacheServiceCollection::trackForUrl( const QUrl &url )
0078 {
0079     MetaProxy::TrackPtr trackptr( new MetaProxy::Track( url, MetaProxy::Track::ManualLookup ) );
0080     AmpacheTrackForUrlWorker *worker = new AmpacheTrackForUrlWorker( url, trackptr,
0081         m_server, m_sessionId, service() );
0082     connect( worker, &AmpacheTrackForUrlWorker::authenticationNeeded,
0083              this, &AmpacheServiceCollection::slotAuthenticationNeeded );
0084     ThreadWeaver::Queue::instance()->enqueue( QSharedPointer<ThreadWeaver::Job>(worker) );
0085 
0086     return Meta::TrackPtr::staticCast( trackptr );
0087 }
0088 
0089 void AmpacheServiceCollection::slotLookupComplete( const Meta::TrackPtr& )
0090 {
0091 }
0092 
0093 void AmpacheTrackForUrlWorker::parseTrack( const QString &xml )
0094 {
0095     //so lets figure out what we got here:
0096     QDomDocument doc( "reply" );
0097     doc.setContent( xml );
0098     QDomElement root = doc.firstChildElement( "root" );
0099     QDomElement song = root.firstChildElement( "song" );
0100 
0101     m_urlTrackId = song.attribute( "id", "0" ).toInt();
0102 
0103     QDomElement element = song.firstChildElement( "title" );
0104 
0105     QString title = element.text();
0106     if ( title.isEmpty() ) title = "Unknown";
0107 
0108     element = song.firstChildElement( "url" );
0109 
0110     m_urlTrack = new Meta::AmpacheTrack( title, m_service );
0111     Meta::TrackPtr trackPtr( m_urlTrack );
0112 
0113     m_urlTrack->setUidUrl( element.text() );
0114     m_urlTrack->setId( m_urlTrackId );
0115 
0116     element = song.firstChildElement( "time" );
0117     m_urlTrack->setLength( element.text().toInt() * 1000 );
0118 
0119     element = song.firstChildElement( "track" );
0120     m_urlTrack->setTrackNumber( element.text().toInt() );
0121 
0122     QDomElement albumElement = song.firstChildElement( "album" );
0123     m_urlAlbumId = albumElement.attribute( "id", "0" ).toInt();
0124 
0125     Meta::AmpacheAlbum *album = new Meta::AmpacheAlbum( albumElement.text() );
0126 
0127     QDomElement artElement = song.firstChildElement( "art" );
0128     album->setCoverUrl( artElement.text() );
0129 
0130     album->addTrack( trackPtr );
0131     m_urlTrack->setAlbumPtr( Meta::AlbumPtr( album ) );
0132 
0133     QDomElement artistElement = song.firstChildElement( "artist" );
0134     Meta::ServiceArtist *artist = new Meta::ServiceArtist( artistElement.text() );
0135 
0136     Meta::ArtistPtr artistPtr( artist );
0137     m_urlTrack->setArtist( artistPtr );
0138     album->setAlbumArtist( artistPtr );
0139 }
0140 
0141 AmpacheTrackForUrlWorker::AmpacheTrackForUrlWorker( const QUrl &url,
0142                                                     const MetaProxy::TrackPtr &track,
0143                                                     const QUrl &server,
0144                                                     const QString &sessionId,
0145                                                     ServiceBase *service )
0146     : Amarok::TrackForUrlWorker( url )
0147     , m_proxy( track )
0148     , m_server( server )
0149     , m_sessionId( sessionId )
0150     , m_service( service )
0151 {
0152 }
0153 
0154 AmpacheTrackForUrlWorker::~AmpacheTrackForUrlWorker()
0155 {}
0156 
0157 void
0158 AmpacheTrackForUrlWorker::run(ThreadWeaver::JobPointer self, ThreadWeaver::Thread *thread)
0159 {
0160     Q_UNUSED( self )
0161     Q_UNUSED( thread )
0162 
0163     m_urlTrack = nullptr;
0164     m_urlAlbum = nullptr;
0165     m_urlArtist = nullptr;
0166 
0167     m_urlTrackId = 0;
0168     m_urlAlbumId = 0;
0169     m_urlArtistId = 0;
0170 
0171     //send url_to_song to Ampache
0172 
0173     QUrl requestUrl = m_server;
0174     requestUrl.setPath( m_server.path() + QStringLiteral("/server/xml.server.php") );
0175     QUrlQuery query;
0176     query.addQueryItem( "action", "url_to_song" );
0177     query.addQueryItem( "auth", m_sessionId );
0178     query.addQueryItem( "url", m_url.toEncoded() );
0179     requestUrl.setQuery( query );
0180 
0181     QNetworkRequest req( requestUrl );
0182     QNetworkReply *reply = The::networkAccessManager()->get( req );
0183 
0184     if( reply->waitForReadyRead(-1) )
0185     {
0186         if( reply->error() == QNetworkReply::ContentAccessDenied )
0187         {
0188             debug() << "Trying to re-authenticate Ampache..";
0189             Q_EMIT authenticationNeeded();
0190         }
0191     }
0192     parseTrack( reply->readAll() );
0193     m_track = Meta::TrackPtr( m_urlTrack );
0194     m_proxy->updateTrack( m_track );
0195     reply->deleteLater();
0196 }