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

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 "ScriptableService.h"
0018 
0019 #include "scripting/scriptmanager/ScriptManager.h"
0020 #include "browsers/CollectionTreeItem.h"
0021 #include "browsers/SingleCollectionTreeItemModel.h"
0022 #include "browsers/servicebrowser/ServiceBrowser.h"
0023 #include "core/support/Amarok.h"
0024 #include "core/support/Debug.h"
0025 #include "services/scriptable/ScriptableServiceCollectionTreeModel.h"
0026 #include "services/scriptable/ScriptableServiceInfoParser.h"
0027 #include "widgets/SearchWidget.h"
0028 
0029 #include <QStandardPaths>
0030 
0031 using namespace Meta;
0032 
0033 ScriptableService::ScriptableService( const QString & name )
0034     : ServiceBase( name, nullptr )
0035     , m_polished( false )
0036     , m_name( name )
0037     , m_trackIdCounter( 0 )
0038     , m_albumIdCounter( 0 )
0039     , m_artistIdCounter( 0 )
0040     , m_genreIdCounter( 0 )
0041 {
0042     DEBUG_BLOCK
0043     debug() << "creating ScriptableService " << name;
0044     m_collection = nullptr;
0045     m_bottomPanel->hide();
0046 }
0047 
0048 ScriptableService::~ScriptableService()
0049 {
0050     m_collection->deleteLater();
0051 }
0052 
0053 void ScriptableService::init( int levels, const QString & rootHtml, bool showSearchBar )
0054 {
0055     DEBUG_BLOCK
0056     m_levels = levels;
0057     m_rootHtml = rootHtml;
0058     m_hasSearchBar = showSearchBar;
0059     m_searchWidget->showAdvancedButton( false );
0060     setInfoParser( new ScriptableServiceInfoParser( m_name ) );
0061     m_collection = new Collections::ScriptableServiceCollection( m_name );
0062     m_collection->setLevels( levels );
0063 
0064     if ( !showSearchBar )
0065         m_searchWidget->hide();
0066 }
0067 
0068 Collections::ServiceCollection * ScriptableService::collection()
0069 {
0070     return m_collection;
0071 }
0072 
0073 
0074 int ScriptableService::insertItem( int level, int parentId, const QString & name, const QString & infoHtml, const QString & callbackData, const QString & playableUrl,
0075                                    const QString & albumOverride, const QString & artistOverride, const QString & genreOverride,
0076                                    const QString & composerOverride, int yearOverride, const QString &coverUrl  )
0077 {
0078 
0079     /*
0080     please don't remove this block as I regularly need it for debugging - nhn
0081     DEBUG_BLOCK
0082     debug() << "level: " << level;
0083     debug() << "parentId: " << parentId;
0084     debug() << "name: " << name;
0085     debug() << "infoHtml: " << infoHtml;
0086     debug() << "callbackData: " << callbackData;
0087     debug() << "playableUrl: " << playableUrl;
0088 
0089     debug() << "albumOverride: " << albumOverride;
0090     debug() << "artistOverride: " << artistOverride;
0091     debug() << "coverUrl: " << coverUrl;*/
0092 
0093     if ( ( level +1 > m_levels ) || level < 0 )
0094         return -1;
0095 
0096     switch ( level ) {
0097 
0098         case 0:
0099         {
0100             if( !callbackData.isEmpty() || playableUrl.isEmpty() )
0101                 return -1;
0102 
0103             AmarokSharedPointer<ScriptableServiceTrack> track( new ScriptableServiceTrack( name ) );
0104             track->setAlbumId( parentId );
0105             track->setUidUrl( playableUrl );
0106             track->setServiceName( m_name );
0107             track->setDescription( infoHtml );
0108 
0109             if ( !m_customEmblem.isNull() )
0110                 track->setServiceEmblem( m_customEmblem );
0111             else
0112                 track->setServiceEmblem( QPixmap( QStandardPaths::locate( QStandardPaths::GenericDataLocation, QStringLiteral("amarok/images/emblem-scripted.png") ) ) );
0113 
0114             if ( !m_customScalableEmblem.isEmpty() )
0115                 track->setServiceScalableEmblem( m_customScalableEmblem );
0116             else
0117                 track->setServiceEmblem( QStandardPaths::locate( QStandardPaths::GenericDataLocation, QStringLiteral("amarok/images/emblem-scripted-scalable.svgz") ) );
0118 
0119             if ( !albumOverride.isEmpty() )
0120                 track->setAlbumName( albumOverride );
0121             if ( !artistOverride.isEmpty() )
0122                 track->setArtistName( artistOverride );
0123             if ( !genreOverride.isEmpty() )
0124                 track->setGenreName( genreOverride );
0125             if ( !composerOverride.isEmpty() )
0126                 track->setComposerName( composerOverride );
0127             if ( yearOverride != 0 )
0128                 track->setYearNumber( yearOverride );
0129             if ( !coverUrl.isEmpty() )
0130                 track->setCustomAlbumCoverUrl( coverUrl );
0131 
0132             return addTrack( track.data() );
0133             break;
0134             
0135         } case 1:
0136         {
0137             if ( callbackData.isEmpty() || !playableUrl.isEmpty() )
0138                 return -1;
0139 
0140             ScriptableServiceAlbum * album = new ScriptableServiceAlbum( name );
0141             album->setCallbackString( callbackData );
0142             album->setArtistId( parentId );
0143             album->setDescription( infoHtml );
0144             album->setServiceName( m_name );
0145             //debug() << "setting coverUrl: " << coverUrl;
0146             album->setCoverUrl( coverUrl );
0147 
0148             album->setServiceName( m_name );
0149             album->setDescription( infoHtml );
0150 
0151             if ( !m_customEmblem.isNull() )
0152                 album->setServiceEmblem( m_customEmblem );
0153             else
0154                 album->setServiceEmblem( QPixmap( QStandardPaths::locate( QStandardPaths::GenericDataLocation, QStringLiteral("amarok/images/emblem-scripted.png") ) ) );
0155 
0156             if ( !m_customScalableEmblem.isEmpty() )
0157                 album->setServiceScalableEmblem( m_customScalableEmblem );
0158             else
0159                 album->setServiceEmblem( QStandardPaths::locate( QStandardPaths::GenericDataLocation, QStringLiteral("amarok/images/emblem-scripted-scalable.svgz") ) );
0160             
0161             return addAlbum( album );
0162             
0163         } case 2:
0164         {
0165             if ( callbackData.isEmpty() || !playableUrl.isEmpty() )
0166                 return -1;
0167 
0168             ScriptableServiceArtist * artist = new ScriptableServiceArtist( name );
0169             artist->setCallbackString( callbackData );
0170             artist->setGenreId( parentId );
0171             artist->setDescription( infoHtml );
0172             artist->setServiceName( m_name );
0173 
0174             artist->setServiceName( m_name );
0175             artist->setDescription( infoHtml );
0176 
0177             if ( !m_customEmblem.isNull() )
0178                 artist->setServiceEmblem( m_customEmblem );
0179             else
0180                 artist->setServiceEmblem( QPixmap( QStandardPaths::locate( QStandardPaths::GenericDataLocation, QStringLiteral("amarok/images/emblem-scripted.png") ) ) );
0181 
0182             if ( !m_customScalableEmblem.isEmpty() )
0183                 artist->setServiceScalableEmblem( m_customScalableEmblem );
0184             else
0185                 artist->setServiceEmblem( QStandardPaths::locate( QStandardPaths::GenericDataLocation, QStringLiteral("amarok/images/emblem-scripted-scalable.svgz") ) );
0186 
0187             
0188             return addArtist( artist );
0189             
0190         } case 3:
0191         {
0192             
0193             if ( callbackData.isEmpty() ||  !playableUrl.isEmpty() || parentId != -1 )
0194                 return -1;
0195 
0196             ScriptableServiceGenre * genre = new ScriptableServiceGenre( name );
0197             genre->setCallbackString( callbackData );
0198             genre->setDescription( infoHtml );
0199             genre->setServiceName( m_name );
0200 
0201             genre->setServiceName( m_name );
0202             genre->setDescription( infoHtml );
0203 
0204             if ( !m_customEmblem.isNull() )
0205                 genre->setServiceEmblem( m_customEmblem );
0206             else
0207                 genre->setServiceEmblem( QPixmap( QStandardPaths::locate( QStandardPaths::GenericDataLocation, QStringLiteral("amarok/images/emblem-scripted.png") ) ) );
0208 
0209             if ( !m_customScalableEmblem.isEmpty() )
0210                 genre->setServiceScalableEmblem( m_customScalableEmblem );
0211             else
0212                 genre->setServiceEmblem( QStandardPaths::locate( QStandardPaths::GenericDataLocation, QStringLiteral("amarok/images/emblem-scripted-scalable.svgz") ) );
0213 
0214             
0215             return addGenre( genre );
0216             
0217         }
0218     }
0219     return -1;
0220 }
0221 
0222 
0223 int ScriptableService::addTrack( ScriptableServiceTrack * track )
0224 {
0225     int artistId = -1;
0226     int genreId = -1;
0227 
0228     TrackPtr trackPtr = TrackPtr( track );
0229     m_collection->acquireWriteLock();
0230     m_collection->addTrack( trackPtr );
0231     m_collection->releaseLock();
0232 
0233     m_trackIdCounter++;
0234     track->setId( m_trackIdCounter );
0235 
0236     
0237     int albumId = track->albumId();
0238 
0239     //handle albums
0240     if ( m_levels > 1 ) {
0241 
0242         if ( !m_ssAlbumIdMap.contains( albumId ) ){
0243             return -1;
0244         }
0245 
0246         ScriptableServiceAlbum * album = m_ssAlbumIdMap.value( albumId );
0247         
0248         track->setAlbum( album->prettyName() );
0249         track->setAlbumPtr( AlbumPtr( album ) );
0250         album->addTrack( trackPtr );
0251 
0252         artistId = album->artistId();
0253 
0254      }
0255 
0256      if ( m_levels > 2 ) {
0257 
0258          if ( !m_ssArtistIdMap.contains( artistId ) ) {
0259              return -1;
0260          }
0261 
0262          ScriptableServiceArtist * artist = m_ssArtistIdMap.value( artistId );
0263          track->setArtist( artist->prettyName() );
0264          track->setArtist( ArtistPtr( artist ) );
0265          artist->addTrack( trackPtr );
0266 
0267          genreId = artist->genreId();
0268      }
0269 
0270      if ( m_levels == 4) {
0271          
0272          if ( !m_ssGenreIdMap.contains( genreId ) ) {
0273              return -1;
0274          }
0275 
0276          ScriptableServiceGenre * genre = m_ssGenreIdMap.value( genreId );
0277          track->setGenre( genre->prettyName() );
0278          track->setGenre( GenrePtr( genre ) );
0279          genre->addTrack( trackPtr );
0280          
0281      }
0282 
0283     m_ssTrackIdMap.insert( m_trackIdCounter, track );
0284     m_collection->acquireWriteLock();
0285     m_collection->addTrack( trackPtr );
0286     m_collection->releaseLock();
0287 
0288     //m_collection->emitUpdated();
0289 
0290     return m_trackIdCounter;
0291 }
0292 
0293 int ScriptableService::addAlbum( ScriptableServiceAlbum * album )
0294 {
0295     int artistId = album->artistId();
0296     if ( m_levels > 2 && !m_ssArtistIdMap.contains( artistId ) ) {
0297         delete album;
0298         return -1;
0299     }
0300 
0301     album->setAlbumArtist( ArtistPtr( m_ssArtistIdMap.value( artistId ) ) );
0302 
0303     AlbumPtr albumPtr = AlbumPtr( album );
0304     m_albumIdCounter++;
0305     album->setId( m_albumIdCounter );
0306     m_ssAlbumIdMap.insert( m_albumIdCounter, album );
0307     m_collection->acquireWriteLock();
0308     m_collection->addAlbum( albumPtr );
0309     m_collection->releaseLock();
0310     //m_collection->emitUpdated();
0311     return m_albumIdCounter;
0312 }
0313 
0314 int ScriptableService::addArtist( Meta::ScriptableServiceArtist * artist )
0315 {
0316     int genreId = artist->genreId();
0317     if (  m_levels > 3 && !m_ssGenreIdMap.contains( genreId ) ) {
0318         delete artist;
0319         return -1;
0320     }
0321     
0322     ArtistPtr artistPtr = ArtistPtr( artist );
0323     m_artistIdCounter++;
0324     artist->setId( m_artistIdCounter );
0325     m_ssArtistIdMap.insert( m_artistIdCounter, artist );
0326     m_collection->acquireWriteLock();
0327     m_collection->addArtist( artistPtr );
0328     m_collection->releaseLock();
0329 
0330     return m_artistIdCounter;
0331 
0332 }
0333 
0334 int ScriptableService::addGenre( Meta::ScriptableServiceGenre * genre )
0335 {
0336     GenrePtr genrePtr = GenrePtr( genre );
0337     m_genreIdCounter++;
0338 
0339     //debug() << "adding genre: " << genre->name() << ", with id: " << m_genreIdCounter;
0340     
0341     genre->setId( m_genreIdCounter );
0342     m_ssGenreIdMap.insert( m_genreIdCounter, genre );
0343     m_collection->acquireWriteLock();
0344     m_collection->addGenre( genrePtr );
0345     m_collection->releaseLock();
0346 
0347     return m_genreIdCounter;
0348 }
0349 
0350 void ScriptableService::donePopulating( int parentId )
0351 {
0352     m_collection->donePopulating( parentId );
0353 }
0354 
0355 void ScriptableService::polish()
0356 {
0357 
0358     if ( !m_polished ) {
0359         QList<CategoryId::CatMenuId> viewLevels;
0360 
0361         switch ( m_levels ) {
0362             case 1:
0363                 break;
0364             case 2:
0365                 viewLevels << CategoryId::Album;
0366                 break;
0367             case 3:
0368                 viewLevels << CategoryId::Artist << CategoryId::Album;
0369                 break;
0370             case 4:
0371                 viewLevels << CategoryId::Genre << CategoryId::Artist << CategoryId::Album;
0372                 break;
0373             default:
0374                 return;
0375         }
0376 
0377         m_contentView->setModel( new ScriptableServiceCollectionTreeModel( m_collection, viewLevels ) );
0378         m_polished = true;
0379 
0380     }
0381 
0382     infoChanged( m_rootHtml );
0383 }
0384 
0385 void ScriptableService::setCustomEmblem( const QPixmap &emblem )
0386 {
0387     m_customEmblem = emblem;
0388 }
0389 
0390 QPixmap ScriptableService::customEmblem()
0391 {
0392     return m_customEmblem;
0393 }
0394 
0395 
0396 QString ScriptableService::customScalableEmblem()
0397 {
0398     return m_customScalableEmblem;
0399 }
0400 
0401 
0402 void ScriptableService::setCustomScalableEmblem ( const QString& emblemPath )
0403 {
0404     m_customScalableEmblem = emblemPath;
0405 }
0406 
0407 
0408 
0409 void ScriptableService::setCurrentInfo( const QString & info )
0410 {
0411     infoChanged( info );
0412 }
0413 
0414 
0415 
0416 
0417