File indexing completed on 2024-05-05 04:49:17

0001 /****************************************************************************************
0002  * Copyright (c) 2007 Maximilian Kossick <maximilian.kossick@googlemail.com>            *
0003  * Copyright (c) 2007 Nikolaj Hald Nielsen <nhn@kde.org>                                *
0004  *                                                                                      *
0005  * This program is free software; you can redistribute it and/or modify it under        *
0006  * the terms of the GNU General Public License as published by the Free Software        *
0007  * Foundation; either version 2 of the License, or (at your option) any later           *
0008  * version.                                                                             *
0009  *                                                                                      *
0010  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0011  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0012  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0013  *                                                                                      *
0014  * You should have received a copy of the GNU General Public License along with         *
0015  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0016  ****************************************************************************************/
0017 
0018 #ifndef SERVICEMETABASE_H
0019 #define SERVICEMETABASE_H
0020 
0021 #include "amarok_export.h"
0022 #include "amarokurls/BookmarkMetaActions.h"
0023 #include "core/support/Debug.h"
0024 #include "InfoParserBase.h"
0025 #include "core-impl/meta/proxy/MetaProxy.h"
0026 #include "ServiceCapabilities.h"
0027 
0028 #include <QAction>
0029 #include <QPointer>
0030 #include <QStringList>
0031 
0032 namespace Amarok
0033 {
0034 }
0035 
0036 class AMAROK_EXPORT ServiceMetaFactory
0037 {
0038     public:
0039         explicit ServiceMetaFactory( const QString &dbPrefix );
0040         virtual ~ServiceMetaFactory() {}
0041 
0042         QString tablePrefix() const;
0043 
0044         virtual int getTrackSqlRowCount();
0045         virtual QString getTrackSqlRows();
0046         virtual Meta::TrackPtr createTrack( const QStringList &rows );
0047 
0048         virtual int getAlbumSqlRowCount();
0049         virtual QString getAlbumSqlRows();
0050         virtual Meta::AlbumPtr createAlbum( const QStringList &rows );
0051 
0052         virtual int getArtistSqlRowCount();
0053         virtual QString getArtistSqlRows();
0054         virtual Meta::ArtistPtr createArtist( const QStringList &rows );
0055 
0056         virtual int getGenreSqlRowCount();
0057         virtual QString getGenreSqlRows();
0058         virtual Meta::GenrePtr createGenre( const QStringList &rows );
0059 
0060     private:
0061         QString m_dbTablePrefix;
0062 };
0063 
0064 class AMAROK_EXPORT ServiceDisplayInfoProvider
0065 {
0066     public:
0067         ServiceDisplayInfoProvider() {}
0068         virtual ~ServiceDisplayInfoProvider() {}
0069 
0070         virtual void processInfoOf( InfoParserBase * infoParser ) = 0;
0071 };
0072 
0073 class AMAROK_EXPORT ActionsProvider
0074 {
0075     public:
0076         ActionsProvider() {}
0077         virtual ~ActionsProvider() {}
0078 
0079         virtual QList< QAction *> actions() { DEBUG_BLOCK return QList< QAction *>(); }
0080 };
0081 
0082 class AMAROK_EXPORT SourceInfoProvider
0083 {
0084     public:
0085         SourceInfoProvider() {}
0086         virtual ~SourceInfoProvider() {}
0087 
0088         virtual QString sourceName() { return QString(); }
0089         virtual QString sourceDescription() { return QString(); }
0090         virtual QPixmap emblem()  { return QPixmap(); }
0091         virtual QString scalableEmblem()  { return QString(); }
0092         virtual bool hasSourceInfo() const { return true; }
0093 };
0094 
0095 class AMAROK_EXPORT BookmarkThisProvider : public QObject
0096 {
0097     Q_OBJECT
0098     public:
0099 
0100         BookmarkThisProvider() : QObject() {}
0101         ~BookmarkThisProvider() override {}
0102 
0103         virtual bool isBookmarkable() const { return false; }
0104         virtual QString browserName() const { return QStringLiteral("internet"); }
0105         virtual QString collectionName() const { return QString(); }
0106         virtual bool simpleFiltering() const { return true; }
0107         virtual QAction * bookmarkAction() { return nullptr; }
0108 
0109     protected:
0110         QPointer<QAction> m_bookmarkAction;
0111 };
0112 
0113 
0114 namespace Meta
0115 {
0116 class ServiceTrack;
0117 class ServiceAlbum;
0118 class ServiceArtist;
0119 class ServiceGenre;
0120 class ServiceComposer;
0121 class ServiceYear;
0122 
0123 typedef AmarokSharedPointer<ServiceTrack> ServiceTrackPtr;
0124 typedef AmarokSharedPointer<ServiceArtist> ServiceArtistPtr;
0125 typedef AmarokSharedPointer<ServiceAlbum> ServiceAlbumPtr;
0126 typedef AmarokSharedPointer<ServiceGenre> ServiceGenrePtr;
0127 typedef AmarokSharedPointer<ServiceComposer> ServiceComposerPtr;
0128 typedef AmarokSharedPointer<ServiceYear> ServiceYearPtr;
0129 
0130 typedef QList<ServiceTrackPtr > ServiceTrackList;
0131 typedef QList<ServiceArtistPtr > ServiceArtistList;
0132 typedef QList<ServiceAlbumPtr > ServiceAlbumList;
0133 typedef QList<ServiceComposerPtr> ServiceComposerList;
0134 typedef QList<ServiceGenrePtr > ServiceGenreList;
0135 typedef QList<ServiceYearPtr > ServiceYearList;
0136 
0137 class AMAROK_EXPORT ServiceTrack : public Meta::Track,
0138                                    public ServiceDisplayInfoProvider,
0139                                    public ActionsProvider,
0140                                    public SourceInfoProvider,
0141                                    public BookmarkThisProvider
0142 {
0143     public:
0144         //Give this a displayable name as some services has terrible names for their streams
0145         //ServiceTrack( const QString & name );
0146         explicit ServiceTrack( const QString & name );
0147 
0148         //create track based on an sql query result
0149         explicit ServiceTrack( const QStringList & resultRow );
0150         ~ServiceTrack() override;
0151 
0152         QString name() const override;
0153         virtual QUrl downloadableUrl() const;
0154         QUrl playableUrl() const override;
0155         QString uidUrl() const override;
0156         QString prettyUrl() const override;
0157         QString notPlayableReason() const override;
0158 
0159         AlbumPtr album() const override;
0160         virtual void setAlbum( const QString &newAlbum );
0161 
0162         ArtistPtr artist() const override;
0163         virtual void setArtist( const QString &newArtist );
0164 
0165         GenrePtr genre() const override;
0166         virtual void setGenre( const QString &newGenre );
0167 
0168         ComposerPtr composer() const override;
0169         virtual void setComposer( const QString &newComposer );
0170 
0171         YearPtr year() const override;
0172         virtual void setYear( int newYear );
0173 
0174         virtual void setTitle( const QString &newTitle );
0175 
0176         qreal bpm() const override;
0177 
0178         QString comment() const override;
0179         virtual void setComment( const QString &newComment );
0180 
0181         virtual QString description() const;
0182         virtual void setDescription( const QString &newDescription );
0183 
0184         qint64 length() const override;
0185 
0186         int filesize() const override;
0187         int sampleRate() const override;
0188         int bitrate() const override;
0189 
0190         int trackNumber() const override;
0191         virtual void setTrackNumber( int newTrackNumber );
0192 
0193         int discNumber() const override;
0194         virtual void setDiscNumber( int newDiscNumber );
0195 
0196         QString type() const override;
0197 
0198         void processInfoOf( InfoParserBase * infoParser ) override;
0199 
0200         bool hasCapabilityInterface( Capabilities::Capability::Type type ) const override
0201         {
0202             return ( type == Capabilities::Capability::Actions ) ||
0203                    ( type == Capabilities::Capability::SourceInfo && hasSourceInfo() ) ||
0204                    ( type == Capabilities::Capability::BookmarkThis ) ||
0205                    ( type == Capabilities::Capability::FindInSource && isBookmarkable() );
0206         }
0207 
0208         Capabilities::Capability* createCapabilityInterface( Capabilities::Capability::Type type ) override
0209         {
0210             if ( type == Capabilities::Capability::Actions )
0211                 return new ServiceActionsCapability( this );
0212             else if ( type == Capabilities::Capability::SourceInfo && hasSourceInfo() )
0213                 return new ServiceSourceInfoCapability( this );
0214             else if ( type == Capabilities::Capability::BookmarkThis )
0215                 return new ServiceBookmarkThisCapability( this );
0216             else if ( type == Capabilities::Capability::FindInSource && isBookmarkable() )
0217                 return new ServiceFindInSourceCapability( this );
0218             return nullptr;
0219         }
0220 
0221         StatisticsPtr statistics() override;
0222 
0223         //ServiceTrack specific methods
0224 
0225         virtual void setAlbumPtr( const Meta::AlbumPtr &album );
0226         void setArtist( const Meta::ArtistPtr &artist );
0227         void setComposer( const Meta::ComposerPtr &composer );
0228         void setGenre( const Meta::GenrePtr &genre );
0229         void setYear( const Meta::YearPtr &year );
0230         void setStatisticsProvider( const Meta::StatisticsPtr &provider );
0231 
0232         void setLength( qint64 length );
0233 
0234         void setId( int id );
0235         int  id( ) const;
0236         void setAlbumId( int albumId );
0237         int  albumId() const;
0238         void setArtistId( int id );
0239         int  artistId() const;
0240         virtual void setUidUrl( const QString &url );
0241         void setDownloadableUrl( const QString &url );
0242 
0243     private:
0244         Meta::StatisticsPtr m_statsStore;
0245         ArtistPtr   m_artist;
0246         AlbumPtr    m_album;
0247         GenrePtr    m_genre;
0248         ComposerPtr m_composer;
0249         YearPtr     m_year;
0250 
0251         int     m_id;
0252         int     m_trackNumber;
0253         qint64     m_length;
0254         QString m_description;
0255         QString m_displayUrl;
0256         QString m_playableUrl;
0257         QString m_downloadableUrl;
0258         int     m_albumId;
0259         QString m_albumName;
0260         int     m_artistId;
0261         QString m_artistName;
0262         QString m_name;
0263 
0264 };
0265 
0266 class AMAROK_EXPORT ServiceArtist : public Meta::Artist,
0267                                     public ServiceDisplayInfoProvider,
0268                                     public ActionsProvider,
0269                                     public SourceInfoProvider,
0270                                     public BookmarkThisProvider
0271 {
0272     public:
0273         explicit ServiceArtist( const QStringList & resultRow );
0274         explicit ServiceArtist( const QString & name );
0275         ~ServiceArtist() override;
0276 
0277         QString name() const override;
0278 
0279         TrackList tracks() override;
0280 
0281         void processInfoOf( InfoParserBase * infoParser ) override;
0282 
0283 
0284         bool hasCapabilityInterface( Capabilities::Capability::Type type ) const override
0285         {
0286             return ( type == Capabilities::Capability::Actions ) ||
0287                     ( type == Capabilities::Capability::SourceInfo && hasSourceInfo() ) ||
0288                     ( type == Capabilities::Capability::BookmarkThis );
0289         }
0290 
0291         Capabilities::Capability* createCapabilityInterface( Capabilities::Capability::Type type ) override
0292         {
0293             if ( type == Capabilities::Capability::Actions )
0294                 return new ServiceActionsCapability( this );
0295             else if ( type == Capabilities::Capability::SourceInfo && hasSourceInfo() )
0296                 return new ServiceSourceInfoCapability( this );
0297             else if ( type == Capabilities::Capability::BookmarkThis )
0298                 return new ServiceBookmarkThisCapability( this );
0299             return nullptr;
0300         }
0301 
0302         QAction * bookmarkAction() override {
0303 
0304             if ( isBookmarkable() ) {
0305                 if ( m_bookmarkAction.isNull())
0306                     m_bookmarkAction = QPointer<QAction>( new BookmarkArtistAction( this, ArtistPtr( this ) ) );
0307                 return m_bookmarkAction.data();
0308             }
0309             else
0310                 return nullptr;
0311         }
0312 
0313         //ServiceArtist specific methods
0314 
0315         void addTrack( const TrackPtr &track );
0316 
0317         void setDescription( const QString &description );
0318         QString description( ) const;
0319         void setId( int id );
0320         int id( ) const;
0321         void setTitle( const QString &title );
0322 
0323         void setSourceName( const QString &source ) { m_sourceName = source; }
0324         QString sourceName() override { return m_sourceName; }
0325 
0326     private:
0327         int       m_id;
0328         QString   m_name;
0329         QString   m_description;
0330         TrackList m_tracks;
0331         QString   m_sourceName;
0332 };
0333 
0334 class AMAROK_EXPORT ServiceAlbum : public Meta::Album,
0335                                    public ServiceDisplayInfoProvider,
0336                                    public ActionsProvider,
0337                                    public SourceInfoProvider,
0338                                    public BookmarkThisProvider
0339 {
0340     public:
0341         explicit ServiceAlbum( const QStringList & resultRow );
0342         explicit ServiceAlbum( const QString & name  );
0343         ~ServiceAlbum() override;
0344 
0345         QString name() const override;
0346 
0347         bool isCompilation() const override;
0348         bool canUpdateCompilation() const override;
0349         void setCompilation( bool compilation ) override;
0350 
0351         bool hasAlbumArtist() const override;
0352         ArtistPtr albumArtist() const override;
0353         TrackList tracks() override;
0354 
0355         void processInfoOf( InfoParserBase * infoParser ) override;
0356 
0357         bool hasCapabilityInterface( Capabilities::Capability::Type type ) const override
0358         {
0359             return ( type == Capabilities::Capability::Actions ) ||
0360                     ( type == Capabilities::Capability::SourceInfo && hasSourceInfo() ) ||
0361                     ( type == Capabilities::Capability::BookmarkThis );
0362         }
0363 
0364         Capabilities::Capability* createCapabilityInterface( Capabilities::Capability::Type type ) override
0365         {
0366             if ( type == Capabilities::Capability::Actions )
0367                 return new ServiceActionsCapability( this );
0368             else if ( type == Capabilities::Capability::SourceInfo && hasSourceInfo() )
0369                 return new ServiceSourceInfoCapability( this );
0370             else if ( type == Capabilities::Capability::BookmarkThis )
0371                 return new ServiceBookmarkThisCapability( this );
0372             return nullptr;
0373         }
0374 
0375         QAction * bookmarkAction() override {
0376 
0377             if ( isBookmarkable() ) {
0378                 if ( m_bookmarkAction.isNull())
0379                     m_bookmarkAction = QPointer<QAction>( new BookmarkAlbumAction( this, AlbumPtr( this ) ) );
0380                 return m_bookmarkAction.data();
0381             }
0382             else
0383                 return nullptr;
0384         }
0385 
0386         //ServiceAlbum specific methods
0387         void addTrack( const TrackPtr &track );
0388         void setAlbumArtist( const ArtistPtr &artist );
0389 
0390         void setDescription( const QString &description );
0391         QString description( ) const;
0392 
0393         void setId( int id );
0394         int  id() const;
0395 
0396         void setArtistId( int artistId );
0397         int  artistId( ) const;
0398 
0399         void setArtistName( const QString &name );
0400         QString artistName() const;
0401 
0402         void setTitle( const QString &title );
0403 
0404         void setSourceName( const QString &source ) { m_sourceName = source; }
0405         QString sourceName() override { return m_sourceName; }
0406 
0407     private:
0408         int       m_id;
0409         QString   m_name;
0410         TrackList m_tracks;
0411         bool      m_isCompilation;
0412         ArtistPtr m_albumArtist;
0413         QString   m_description;
0414         int       m_artistId;
0415         QString   m_artistName;
0416         QString   m_sourceName;
0417 };
0418 
0419 class AMAROK_EXPORT ServiceGenre : public Meta::Genre,
0420                                    public ServiceDisplayInfoProvider,
0421                                    public ActionsProvider,
0422                                    public SourceInfoProvider,
0423                                    public BookmarkThisProvider
0424 {
0425     public:
0426         explicit ServiceGenre( const QString &name );
0427         explicit ServiceGenre( const QStringList &row );
0428         ~ServiceGenre() override;
0429 
0430         QString name() const override;
0431 
0432         TrackList tracks() override;
0433 
0434         void processInfoOf( InfoParserBase * infoParser ) override;
0435 
0436         bool hasCapabilityInterface( Capabilities::Capability::Type type ) const override
0437         {
0438             return ( type == Capabilities::Capability::Actions ) ||
0439                     ( type == Capabilities::Capability::SourceInfo && hasSourceInfo() ) ||
0440                     ( type == Capabilities::Capability::BookmarkThis );
0441         }
0442 
0443         Capabilities::Capability* createCapabilityInterface( Capabilities::Capability::Type type ) override
0444         {
0445             if ( type == Capabilities::Capability::Actions )
0446                 return new ServiceActionsCapability( this );
0447             else if ( type == Capabilities::Capability::SourceInfo && hasSourceInfo() )
0448                 return new ServiceSourceInfoCapability( this );
0449             else if ( type == Capabilities::Capability::BookmarkThis )
0450                 return new ServiceBookmarkThisCapability( this );
0451             return nullptr;
0452         }
0453 
0454 
0455         //ServiceGenre specific methods
0456         void setId( int id );
0457         int id() const;
0458 
0459         void addTrack( const TrackPtr &track );
0460 
0461         int  albumId();
0462         void setAlbumId( int albumId );
0463 
0464         void setSourceName( const QString &source ) { m_sourceName = source; }
0465         QString sourceName() override { return m_sourceName; }
0466 
0467     private:
0468         int       m_id;
0469         int       m_albumId;
0470         QString   m_name;
0471         TrackList m_tracks;
0472         QString   m_sourceName;
0473 };
0474 
0475 class AMAROK_EXPORT ServiceComposer : public Meta::Composer,
0476                                       public ServiceDisplayInfoProvider,
0477                                       public ActionsProvider,
0478                                       public SourceInfoProvider,
0479                                       public BookmarkThisProvider
0480 {
0481     public:
0482         explicit ServiceComposer( const QString &name );
0483         ~ServiceComposer() override;
0484 
0485         QString name() const override;
0486 
0487         TrackList tracks() override;
0488 
0489         void processInfoOf( InfoParserBase * infoParser ) override;
0490 
0491         bool hasCapabilityInterface( Capabilities::Capability::Type type ) const override
0492         {
0493             return ( type == Capabilities::Capability::Actions ) ||
0494                     ( type == Capabilities::Capability::SourceInfo && hasSourceInfo() ) ||
0495                     ( type == Capabilities::Capability::BookmarkThis );
0496         }
0497 
0498         Capabilities::Capability* createCapabilityInterface( Capabilities::Capability::Type type ) override
0499         {
0500             if ( type == Capabilities::Capability::Actions )
0501                 return new ServiceActionsCapability( this );
0502             else if ( type == Capabilities::Capability::SourceInfo && hasSourceInfo() )
0503                 return new ServiceSourceInfoCapability( this );
0504             else if ( type == Capabilities::Capability::BookmarkThis )
0505                 return new ServiceBookmarkThisCapability( this );
0506             return nullptr;
0507         }
0508 
0509         //ServiceComposer specific methods
0510         void addTrack( const ServiceTrackPtr &track );
0511 
0512     private:
0513         QString   m_name;
0514         TrackList m_tracks;
0515 };
0516 
0517 class AMAROK_EXPORT ServiceYear : public Meta::Year,
0518                                   public ServiceDisplayInfoProvider,
0519                                   public ActionsProvider,
0520                                   public SourceInfoProvider,
0521                                   public BookmarkThisProvider
0522 {
0523     public:
0524         explicit ServiceYear( const QString &name );
0525         ~ServiceYear() override;
0526 
0527         QString name() const override;
0528 
0529         TrackList tracks() override;
0530 
0531         void processInfoOf( InfoParserBase * infoParser ) override;
0532 
0533         bool hasCapabilityInterface( Capabilities::Capability::Type type ) const override
0534         {
0535             return ( type == Capabilities::Capability::Actions ) ||
0536                     ( type == Capabilities::Capability::SourceInfo && hasSourceInfo() ) ||
0537                     ( type == Capabilities::Capability::BookmarkThis );
0538         }
0539 
0540         Capabilities::Capability* createCapabilityInterface( Capabilities::Capability::Type type ) override
0541         {
0542             if ( type == Capabilities::Capability::Actions )
0543                 return new ServiceActionsCapability( this );
0544             else if ( type == Capabilities::Capability::SourceInfo && hasSourceInfo() )
0545                 return new ServiceSourceInfoCapability( this );
0546             else if ( type == Capabilities::Capability::BookmarkThis )
0547                 return new ServiceBookmarkThisCapability( this );
0548             return nullptr;
0549         }
0550 
0551         //ServiceYear specific methods
0552         void addTrack( const ServiceTrackPtr &track );
0553 
0554     private:
0555         QString   m_name;
0556         TrackList m_tracks;
0557 };
0558 
0559 }
0560 
0561 #endif
0562