File indexing completed on 2024-05-19 04:50:13
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 "JamendoService.h" 0018 0019 #include "browsers/CollectionTreeItem.h" 0020 #include "browsers/CollectionTreeView.h" 0021 #include "browsers/SingleCollectionTreeItemModel.h" 0022 #include "core-impl/collections/support/CollectionManager.h" 0023 #include "core/support/Debug.h" 0024 #include "core/support/Components.h" 0025 #include "core/logger/Logger.h" 0026 #include "EngineController.h" 0027 #include "JamendoInfoParser.h" 0028 #include "ServiceSqlRegistry.h" 0029 #include "widgets/SearchWidget.h" 0030 0031 #include <QAction> 0032 #include <QDesktopServices> 0033 #include <QHBoxLayout> 0034 #include <QMenuBar> 0035 #include <QStandardPaths> 0036 #include <QTemporaryFile> 0037 #include <QToolBar> 0038 #include <QToolButton> 0039 0040 #include <KPluginFactory> 0041 #include <KShell> 0042 #include <ThreadWeaver/ThreadWeaver> 0043 0044 using namespace Meta; 0045 0046 0047 JamendoServiceFactory::JamendoServiceFactory() 0048 : ServiceFactory() 0049 { 0050 } 0051 0052 void JamendoServiceFactory::init() 0053 { 0054 ServiceBase* service = new JamendoService( this, "Jamendo.com" ); 0055 m_initialized = true; 0056 emit newService( service ); 0057 } 0058 0059 QString 0060 JamendoServiceFactory::name() 0061 { 0062 return "Jamendo.com"; 0063 } 0064 0065 KConfigGroup 0066 JamendoServiceFactory::config() 0067 { 0068 return Amarok::config( "Service_Jamendo" ); 0069 } 0070 0071 JamendoService::JamendoService( JamendoServiceFactory* parent, const QString & name) 0072 : ServiceBase( name, parent ) 0073 , m_currentAlbum( 0 ) 0074 , m_xmlParser( 0 ) 0075 { 0076 setShortDescription( i18n( "An archive of free, Creative Commons licensed music" ) ); 0077 setIcon( QIcon::fromTheme( "view-services-jamendo-amarok" ) ); 0078 0079 setLongDescription( i18n( "Jamendo.com puts artists and music lovers in touch with each other. The site allows artists to upload their own albums to share them with the world and users to download all of them for free. Listen to and download all Jamendo.com contents from within Amarok." ) ); 0080 0081 setImagePath( QStandardPaths::locate( QStandardPaths::GenericDataLocation, "amarok/images/hover_info_jamendo.png" ) ); 0082 0083 ServiceMetaFactory * metaFactory = new JamendoMetaFactory( "jamendo", this ); 0084 ServiceSqlRegistry * registry = new ServiceSqlRegistry( metaFactory ); 0085 m_collection = new Collections::ServiceSqlCollection( "jamendo", "Jamendo.com", metaFactory, registry ); 0086 CollectionManager::instance()->addTrackProvider( m_collection ); 0087 setServiceReady( true ); 0088 } 0089 0090 JamendoService::~JamendoService() 0091 { 0092 DEBUG_BLOCK 0093 0094 if( m_collection ) 0095 { 0096 CollectionManager::instance()->removeTrackProvider( m_collection ); 0097 m_collection->deleteLater(); 0098 m_collection = 0; 0099 } 0100 0101 //if currently running, stop it or we will get crashes 0102 if( m_xmlParser ) { 0103 m_xmlParser->requestAbort(); 0104 delete m_xmlParser; 0105 m_xmlParser = 0; 0106 } 0107 } 0108 0109 void 0110 JamendoService::polish() 0111 { 0112 generateWidgetInfo(); 0113 if ( m_polished ) 0114 return; 0115 0116 BoxWidget *bottomPanelLayout = new BoxWidget( false, m_bottomPanel ); 0117 0118 m_updateListButton = new QPushButton; 0119 m_updateListButton->setParent( bottomPanelLayout ); 0120 m_updateListButton->setText( i18nc( "Fetch new information from the website", "Update" ) ); 0121 m_updateListButton->setObjectName( "updateButton" ); 0122 m_updateListButton->setIcon( QIcon::fromTheme( "view-refresh-amarok" ) ); 0123 0124 m_downloadButton = new QPushButton; 0125 m_downloadButton->setParent( bottomPanelLayout ); 0126 m_downloadButton->setText( i18n( "Download" ) ); 0127 m_downloadButton->setObjectName( "downloadButton" ); 0128 m_downloadButton->setIcon( QIcon::fromTheme( "download-amarok" ) ); 0129 m_downloadButton->setEnabled( false ); 0130 0131 connect( m_updateListButton, &QPushButton::clicked, this, &JamendoService::updateButtonClicked ); 0132 connect( m_downloadButton, &QPushButton::clicked, this, &JamendoService::download ); 0133 0134 setInfoParser( new JamendoInfoParser() ); 0135 0136 QList<CategoryId::CatMenuId> levels; 0137 levels << CategoryId::Genre << CategoryId::Artist << CategoryId::Album; 0138 0139 setModel( new SingleCollectionTreeItemModel( m_collection, levels ) ); 0140 0141 connect( static_cast<ServiceCollectionTreeView*>( m_contentView ), &ServiceCollectionTreeView::itemSelected, 0142 this, &JamendoService::itemSelected ); 0143 0144 QMenu *filterMenu = new QMenu( 0 ); 0145 0146 // QAction *action = filterMenu->addAction( i18n("Artist") ); 0147 // connect( action, SIGNAL(triggered(bool)), SLOT(sortByArtist()) ); 0148 // 0149 // action = filterMenu->addAction( i18n( "Artist / Album" ) ); 0150 // connect( action, SIGNAL(triggered(bool)), SLOT(sortByArtistAlbum()) ); 0151 // 0152 // action = filterMenu->addAction( i18n( "Album" ) ); 0153 // connect( action, SIGNAL(triggered(bool)), SLOT(sortByAlbum()) ); 0154 0155 QAction *action = filterMenu->addAction( i18n( "Genre / Artist" ) ); 0156 connect( action, &QAction::triggered, this, &JamendoService::sortByGenreArtist ); 0157 0158 action = filterMenu->addAction( i18n( "Genre / Artist / Album" ) ); 0159 connect( action, &QAction::triggered, this, &JamendoService::sortByGenreArtistAlbum ); 0160 0161 QAction *filterMenuAction = new QAction( QIcon::fromTheme( "preferences-other" ), i18n( "Sort Options" ), this ); 0162 filterMenuAction->setMenu( filterMenu ); 0163 0164 m_searchWidget->toolBar()->addSeparator(); 0165 m_searchWidget->toolBar()->addAction( filterMenuAction ); 0166 0167 QToolButton *tbutton = qobject_cast< QToolButton* >( m_searchWidget->toolBar()->widgetForAction( filterMenuAction ) ); 0168 if( tbutton ) 0169 tbutton->setPopupMode( QToolButton::InstantPopup ); 0170 0171 // m_menubar->show(); 0172 0173 m_polished = true; 0174 } 0175 0176 void 0177 JamendoService::updateButtonClicked() 0178 { 0179 m_updateListButton->setEnabled( false ); 0180 0181 debug() << "JamendoService: start downloading xml file"; 0182 0183 QTemporaryFile tempFile; 0184 // tempFile.setSuffix( ".gz" ); 0185 tempFile.setAutoRemove( false ); //file will be removed in JamendoXmlParser 0186 if( !tempFile.open() ) 0187 return; //error 0188 m_tempFileName = tempFile.fileName(); 0189 m_listDownloadJob = KIO::file_copy( 0190 /* Deprecated */ QUrl("http://imgjam.com/data/dbdump_artistalbumtrack.xml.gz"), 0191 QUrl::fromLocalFile( m_tempFileName ), 0700 , KIO::HideProgressInfo | KIO::Overwrite ); 0192 0193 Amarok::Logger::newProgressOperation( m_listDownloadJob, i18n( "Downloading Jamendo.com database..." ), this, SLOT(listDownloadCancelled()) ); 0194 0195 connect( m_listDownloadJob, &KJob::result, 0196 this, &JamendoService::listDownloadComplete ); 0197 } 0198 0199 void 0200 JamendoService::listDownloadComplete(KJob * downloadJob) 0201 { 0202 if( downloadJob != m_listDownloadJob ) 0203 return ; //not the right job, so let's ignore it 0204 debug() << "JamendoService: xml file download complete"; 0205 0206 m_listDownloadJob = 0; 0207 //testing 0208 if ( downloadJob->error() != 0 ) 0209 { 0210 //TODO: error handling here 0211 m_updateListButton->setEnabled( true ); // otherwise button will remain inactive in case of error 0212 return; 0213 } 0214 0215 Amarok::Logger::shortMessage( i18n( "Updating the local Jamendo database." ) ); 0216 debug() << "JamendoService: create xml parser"; 0217 0218 if( m_xmlParser == 0 ) 0219 m_xmlParser = new JamendoXmlParser( m_tempFileName ); 0220 connect( m_xmlParser, &JamendoXmlParser::doneParsing, this, &JamendoService::doneParsing ); 0221 0222 ThreadWeaver::Queue::instance()->enqueue( QSharedPointer<ThreadWeaver::Job>(m_xmlParser) ); 0223 downloadJob->deleteLater(); 0224 } 0225 0226 void 0227 JamendoService::listDownloadCancelled() 0228 { 0229 m_listDownloadJob->kill(); 0230 m_listDownloadJob = 0; 0231 debug() << "Aborted xml download"; 0232 0233 m_updateListButton->setEnabled( true ); 0234 } 0235 0236 void 0237 JamendoService::doneParsing() 0238 { 0239 debug() << "JamendoService: done parsing"; 0240 m_updateListButton->setEnabled( true ); 0241 // model->setGenre("All"); 0242 //delete sender 0243 sender()->deleteLater(); 0244 m_xmlParser = 0; 0245 m_collection->emitUpdated(); 0246 } 0247 0248 void 0249 JamendoService::itemSelected( CollectionTreeItem * selectedItem ) 0250 { 0251 DEBUG_BLOCK 0252 0253 //we only enable the download button if there is only one item selected and it happens to 0254 //be an album or a track 0255 DataPtr dataPtr = selectedItem->data(); 0256 0257 if ( typeid( *dataPtr.data() ) == typeid( JamendoTrack ) ) 0258 { 0259 debug() << "is right type (track)"; 0260 JamendoTrack * track = static_cast<JamendoTrack *> ( dataPtr.data() ); 0261 m_currentAlbum = static_cast<JamendoAlbum *> ( track->album().data() ); 0262 m_downloadButton->setEnabled( true ); 0263 } 0264 else if ( typeid( * dataPtr.data() ) == typeid( JamendoAlbum ) ) 0265 { 0266 m_currentAlbum = static_cast<JamendoAlbum *> ( dataPtr.data() ); 0267 debug() << "is right type (album) named " << m_currentAlbum->name(); 0268 m_downloadButton->setEnabled( true ); 0269 } 0270 else 0271 { 0272 debug() << "is wrong type"; 0273 m_downloadButton->setEnabled( false ); 0274 } 0275 return; 0276 } 0277 0278 void 0279 JamendoService::download() // SLOT 0280 { 0281 DEBUG_BLOCK 0282 0283 if ( !m_polished ) 0284 polish(); 0285 0286 CollectionTreeView *treeView = static_cast<CollectionTreeView*>( view() ); 0287 treeView->copySelectedToLocalCollection(); 0288 }