1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-07-31 11:20:22 +02:00

Adding charts for Billboard and Itunes

This commit is contained in:
Hugo Lindström
2011-10-06 23:00:19 +02:00
parent 049184bdfd
commit 9caf9fc98f
4 changed files with 114 additions and 129 deletions

View File

@@ -52,9 +52,20 @@ ChartsPlugin::ChartsPlugin()
tDebug() << "ChartsPlugin: InfoChart fetching possible resources"; tDebug() << "ChartsPlugin: InfoChart fetching possible resources";
QUrl url = QUrl(CHART_URL); /// Add resources here
QNetworkReply* reply = lastfm::nam()->get( QNetworkRequest( url ) ); m_chartResources << "billboard"
connect( reply, SIGNAL( finished() ), SLOT( chartResources() ) ); << "itunes";
/// Then get each chart from resource
if(!m_chartResources.isEmpty()){
foreach(QVariant resource, m_chartResources)
{
QUrl url = QUrl( QString( CHART_URL "source/%1" ).arg(resource.toString() ) );
QNetworkReply* reply = lastfm::nam()->get( QNetworkRequest( url ) );
connect( reply, SIGNAL( finished() ), SLOT( chartTypes() ) );
}
}
m_supportedGetTypes << InfoChart << InfoChartCapabilities; m_supportedGetTypes << InfoChart << InfoChartCapabilities;
@@ -112,29 +123,29 @@ ChartsPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoTy
} }
void void
ChartsPlugin::fetchChart( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData ) ChartsPlugin::fetchChart( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
{ {
if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() ) if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() )
{ {
dataError( requestId, requestData ); dataError( requestId, requestData );
return; return;
} }
InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >(); InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
Tomahawk::InfoSystem::InfoCriteriaHash criteria; Tomahawk::InfoSystem::InfoCriteriaHash criteria;
if ( !hash.contains( "chart_id" ) )
/// Each request needs to contain both a id and source
if ( !hash.contains( "chart_id" ) && !hash.contains( "chart_source" ) )
{ {
dataError( requestId, requestData ); dataError( requestId, requestData );
return; return;
} else {
criteria["chart_id"] = hash["chart_id"];
}
if ( hash.contains( "chart_source" ) )
{
criteria["chart_source"] = hash["chart_source"];
} }
/// Set the criterias for current chart
criteria["chart_id"] = hash["chart_id"];
criteria["chart_source"] = hash["chart_source"];
emit getCachedInfo( requestId, criteria, 0, requestData ); emit getCachedInfo( requestId, criteria, 0, requestData );
} }
@@ -147,7 +158,8 @@ ChartsPlugin::fetchChartCapabilities( uint requestId, Tomahawk::InfoSystem::Info
dataError( requestId, requestData ); dataError( requestId, requestData );
return; return;
} }
InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
//InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
Tomahawk::InfoSystem::InfoCriteriaHash criteria; Tomahawk::InfoSystem::InfoCriteriaHash criteria;
emit getCachedInfo( requestId, criteria, 0, requestData ); emit getCachedInfo( requestId, criteria, 0, requestData );
@@ -168,9 +180,11 @@ ChartsPlugin::notInCacheSlot( uint requestId, QHash<QString, QString> criteria,
case InfoChart: case InfoChart:
{ {
/// Fetch the chart, we need source and id
QUrl url = QUrl( QString( CHART_URL "/source/%1/chart/%2" ).arg( criteria["chart_source"] ).arg( criteria["chart_id"] ) ); QUrl url = QUrl( QString( CHART_URL "/source/%1/chart/%2" ).arg( criteria["chart_source"] ).arg( criteria["chart_id"] ) );
qDebug() << Q_FUNC_INFO << "Getting chart url" << url; qDebug() << Q_FUNC_INFO << "Getting chart url" << url;
/// @todo: Should add ChartPlugin nam here
QNetworkReply* reply = lastfm::nam()->get( QNetworkRequest( url ) ); QNetworkReply* reply = lastfm::nam()->get( QNetworkRequest( url ) );
reply->setProperty( "requestId", requestId ); reply->setProperty( "requestId", requestId );
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) ); reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
@@ -193,12 +207,15 @@ ChartsPlugin::notInCacheSlot( uint requestId, QHash<QString, QString> criteria,
if( !m_chartTypes.isEmpty() ) if( !m_chartTypes.isEmpty() )
foreach( QVariant type, m_chartTypes ) foreach( QVariant type, m_chartTypes )
{ {
// Itunes supplys charts based on geo, for now, only take US charts /// Itunes supplys charts based on geo, for now, only take US charts
/// @todo: Add new breadcrumb option for country?
if( type.toMap().value( "source" ).toString() == chartResource.toString() if( type.toMap().value( "source" ).toString() == chartResource.toString()
&& type.toMap().value( "geo" ).isValid() && type.toMap().value( "geo" ).isValid()
&& type.toMap().value( "geo" ).toString() != "us" ) && type.toMap().value( "geo" ).toString() != "us" )
continue; continue;
/// Append each type to its parent source
/// @todo Add chartType enum
if( type.toMap().value( "source" ).toString() == chartResource.toString() ) if( type.toMap().value( "source" ).toString() == chartResource.toString() )
{ {
if( type.toMap().value( "type" ).toString() == "Album" ) if( type.toMap().value( "type" ).toString() == "Album" )
@@ -213,8 +230,13 @@ ChartsPlugin::notInCacheSlot( uint requestId, QHash<QString, QString> criteria,
} }
} }
} }
/// @note For displaying purposes, upper the first letter
/// @note Remeber to lower it when fetching this!
QString chartName = chartResource.toString();
chartName[0] = chartName[0].toUpper();
result.insert( chartResource.toString() , QVariant::fromValue<QVariantMap>( charts ) ); /// Add the possible charts and its types to breadcrumb
result.insert( chartName , QVariant::fromValue<QVariantMap>( charts ) );
} }
emit info( emit info(
requestId, requestId,
@@ -224,8 +246,6 @@ ChartsPlugin::notInCacheSlot( uint requestId, QHash<QString, QString> criteria,
return; return;
} }
default: default:
{ {
tLog() << "Couldn't figure out what to do with this type of request after cache miss"; tLog() << "Couldn't figure out what to do with this type of request after cache miss";
@@ -235,56 +255,13 @@ ChartsPlugin::notInCacheSlot( uint requestId, QHash<QString, QString> criteria,
} }
} }
void
ChartsPlugin::chartResources()
{
tDebug() << "ChartsPlugin: InfoChart resources returned!";
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
if ( reply->error() == QNetworkReply::NoError )
{
QJson::Parser p;
bool ok;
QVariantMap res = p.parse( reply, &ok ).toMap();
if ( !ok )
{
tLog() << "Failed to parse resources" << p.errorString() << "On line" << p.errorLine();
return;
}
m_chartResources = res.value( "chart_sources" ).toList();
qDebug() << "Resources" << m_chartResources;
if(!m_chartResources.isEmpty()){
foreach(QVariant resource, m_chartResources){
tDebug() << "ChartsPlugin: InfoChart fetching possible types for "<< resource.toString();
QUrl url = QUrl( QString( CHART_URL "source/%1" ).arg(resource.toString() ) );
qDebug() << "Getting types from " << url;
QNetworkReply* reply = lastfm::nam()->get( QNetworkRequest( url ) );
connect( reply, SIGNAL( finished() ), SLOT( chartTypes() ) );
}
}
}
}
void void
ChartsPlugin::chartTypes() ChartsPlugin::chartTypes()
{ {
/// Get possible chart type for specific chart source
tDebug() << "ChartsPlugin: InfoChart types returned!"; tDebug() << "ChartsPlugin: InfoChart types returned!";
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() ); QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
if ( reply->error() == QNetworkReply::NoError ) if ( reply->error() == QNetworkReply::NoError )
{ {
QJson::Parser p; QJson::Parser p;
@@ -297,11 +274,9 @@ ChartsPlugin::chartTypes()
return; return;
} }
/// Got types, append!
foreach(QVariant chart, res.value( "charts" ).toMap() ){ foreach(QVariant chart, res.value( "charts" ).toMap() )
m_chartTypes.append(chart); m_chartTypes.append(chart);
qDebug() << "Chart types" << chart;
}
} }
@@ -311,8 +286,8 @@ void
ChartsPlugin::chartReturned() ChartsPlugin::chartReturned()
{ {
/// Chart request returned something! Woho
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() ); QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
QVariantMap returnedData; QVariantMap returnedData;
if ( reply->error() == QNetworkReply::NoError ) if ( reply->error() == QNetworkReply::NoError )
@@ -324,15 +299,16 @@ ChartsPlugin::chartReturned()
if ( !ok ) if ( !ok )
{ {
tLog() << "Failed to parse json from chart lookup:" << p.errorString() << "On line" << p.errorLine(); tLog() << "Failed to parse json from chart lookup:" << p.errorString() << "On line" << p.errorLine();
return; return;
}else qDebug() << res; }
/// SO we have a result, parse it!
QVariantList chartResponse = res.value( "list" ).toList(); QVariantList chartResponse = res.value( "list" ).toList();
QList<ArtistTrackPair> top_tracks; QList<ArtistTrackPair> top_tracks;
QList<ArtistAlbumPair> top_albums; QList<ArtistAlbumPair> top_albums;
/// Deside what type, we need to handle it differently
/// @todo: We allready know the type, append it to breadcrumb hash
if( res.value( "type" ).toString() == "Album" ) if( res.value( "type" ).toString() == "Album" )
setChartType( Album ); setChartType( Album );
@@ -347,57 +323,77 @@ ChartsPlugin::chartReturned()
QString title, artist, album; QString title, artist, album;
QVariantMap chartMap = chartR.toMap(); QVariantMap chartMap = chartR.toMap();
if ( chartMap.contains( "track" ) ) if( !chartMap.isEmpty() )
{ {
title = chartMap.value( "track" ).toString(); title = chartMap.value( "track" ).toString();
album = chartMap.value( "album" ).toString();
artist = chartMap.value( "artist" ).toString(); artist = chartMap.value( "artist" ).toString();
/// Maybe we can use rank later on, to display something nice
/// rank = chartMap.value( "rank" ).toString();
if ( title.isEmpty() && artist.isEmpty() ) // don't have enough... if( chartType() == Album )
{ {
tLog() << "Didn't get an artist and track name from itunes, not enough to build a query on. Aborting" << title << artist << album; /** HACK, billboard chart returns wrong typename **/
if( res.value( "source" ).toString() == "billboard" )
album = chartMap.value( "track" ).toString();
} if ( album.isEmpty() && artist.isEmpty() ) // don't have enough...
else{ {
tLog() << "Didn't get an artist and album name from chart, not enough to build a query on. Aborting" << title << album << artist;
if( chartType() == Album ){
}else
{
qDebug() << Q_FUNC_INFO << album << artist;
ArtistAlbumPair pair; ArtistAlbumPair pair;
pair.artist = artist; pair.artist = artist;
pair.album = title; pair.album = album;
top_albums << pair; top_albums << pair;
}else if( chartType() == Track ){ }
}
else if( chartType() == Track )
{
if ( title.isEmpty() && artist.isEmpty() ) // don't have enough...
{
tLog() << "Didn't get an artist and track name from charts, not enough to build a query on. Aborting" << title << artist << album;
}else{
ArtistTrackPair pair; ArtistTrackPair pair;
pair.artist = artist; pair.artist = artist;
pair.track = title; pair.track = title;
top_tracks << pair; top_tracks << pair;
}
}
} }
} }
} }
if( chartType() == Track ){
tDebug() << "ChartsPlugin:" << "\tgot " << top_tracks.size() << " tracks";
returnedData["tracks"] = QVariant::fromValue( top_tracks );
returnedData["type"] = "tracks";
}
if( chartType() == Album ){ if( chartType() == Track )
tDebug() << "ChartsPlugin:" << "\tgot " << top_albums.size() << " albums"; {
returnedData["albums"] = QVariant::fromValue( top_albums ); tDebug() << "ChartsPlugin:" << "\tgot " << top_tracks.size() << " tracks";
returnedData["type"] = "albums"; returnedData["tracks"] = QVariant::fromValue( top_tracks );
} returnedData["type"] = "tracks";
}
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >(); if( chartType() == Album )
{
tDebug() << "ChartsPlugin:" << "\tgot " << top_albums.size() << " albums";
returnedData["albums"] = QVariant::fromValue( top_albums );
returnedData["type"] = "albums";
}
emit info( Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
reply->property( "requestId" ).toUInt(),
requestData, emit info(
returnedData reply->property( "requestId" ).toUInt(),
); requestData,
// TODO update cache returnedData
);
// TODO update cache
}else qDebug() << "Network error"; }else qDebug() << "Network error";

View File

@@ -52,7 +52,6 @@ public:
public slots: public slots:
void chartReturned(); void chartReturned();
void chartResources();
void chartTypes(); void chartTypes();
void namChangedSlot( QNetworkAccessManager *nam ); void namChangedSlot( QNetworkAccessManager *nam );

View File

@@ -53,14 +53,15 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent )
{ {
ui->setupUi( this ); ui->setupUi( this );
ui->additionsView->setFrameShape( QFrame::NoFrame );
ui->additionsView->setAttribute( Qt::WA_MacShowFocusRect, 0 );
TomahawkUtils::unmarginLayout( layout() ); TomahawkUtils::unmarginLayout( layout() );
TomahawkUtils::unmarginLayout( ui->stackLeft->layout() ); TomahawkUtils::unmarginLayout( ui->stackLeft->layout() );
TomahawkUtils::unmarginLayout( ui->horizontalLayout->layout() ); TomahawkUtils::unmarginLayout( ui->horizontalLayout->layout() );
TomahawkUtils::unmarginLayout( ui->horizontalLayout_2->layout() ); TomahawkUtils::unmarginLayout( ui->horizontalLayout_2->layout() );
TomahawkUtils::unmarginLayout( ui->breadCrumbLeft->layout() ); TomahawkUtils::unmarginLayout( ui->breadCrumbLeft->layout() );
TomahawkUtils::unmarginLayout( ui->verticalLayout2->layout() ); TomahawkUtils::unmarginLayout( ui->verticalLayout->layout() );
//set crumb widgets //set crumb widgets
SiblingCrumbButtonFactory * crumbFactory = new SiblingCrumbButtonFactory; SiblingCrumbButtonFactory * crumbFactory = new SiblingCrumbButtonFactory;
@@ -70,21 +71,16 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent )
ui->breadCrumbLeft->setButtonFactory(crumbFactory); ui->breadCrumbLeft->setButtonFactory(crumbFactory);
ui->breadCrumbLeft->setModel(m_crumbModelLeft); ui->breadCrumbLeft->setModel(m_crumbModelLeft);
ui->breadCrumbLeft->setRootIcon(QIcon( RESPATH "images/charts.png" )); ui->breadCrumbLeft->setRootIcon(QIcon( RESPATH "images/charts.png" ));
//ui->breadCrumbLeft->setSelectionModel(selectionModelLeft);
ui->breadCrumbLeft->setUseAnimation(true); ui->breadCrumbLeft->setUseAnimation(true);
connect(ui->breadCrumbLeft, SIGNAL(currentIndexChanged(QModelIndex)), SLOT(leftCrumbIndexChanged(QModelIndex))); connect(ui->breadCrumbLeft, SIGNAL(currentIndexChanged(QModelIndex)), SLOT(leftCrumbIndexChanged(QModelIndex)));
/*ui->breadCrumbRight->setButtonFactory(crumbFactory); m_albumsModel = new AlbumModel( ui->additionsView );
ui->breadCrumbRight->setRootIcon(QIcon( RESPATH "images/charts.png" )); ui->additionsView->setAlbumModel( m_albumsModel );
ui->breadCrumbRight->setModel(m_crumbModelLeft);
ui->breadCrumbRight->setUseAnimation(true);*/
m_tracksModel = new PlaylistModel( ui->tracksViewLeft ); m_tracksModel = new PlaylistModel( ui->tracksViewLeft );
m_tracksModel->setStyle( TrackModel::ShortWithAvatars ); m_tracksModel->setStyle( TrackModel::ShortWithAvatars );
ui->tracksViewLeft->setFrameShape( QFrame::NoFrame ); ui->tracksViewLeft->setFrameShape( QFrame::NoFrame );
ui->tracksViewLeft->setAttribute( Qt::WA_MacShowFocusRect, 0 ); ui->tracksViewLeft->setAttribute( Qt::WA_MacShowFocusRect, 0 );
ui->tracksViewLeft->overlay()->setEnabled( false ); ui->tracksViewLeft->overlay()->setEnabled( false );
@@ -111,11 +107,6 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent )
ui->artistsViewLeft->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff ); ui->artistsViewLeft->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
ui->artistsViewLeft->header()->setVisible( false ); ui->artistsViewLeft->header()->setVisible( false );
ui->albumsViewLeft->setFrameShape( QFrame::NoFrame );
ui->albumsViewLeft->setAttribute( Qt::WA_MacShowFocusRect, 0 );
m_albumsModel = new AlbumModel( ui->albumsViewLeft );
ui->albumsViewLeft->setAlbumModel( m_albumsModel );
m_timer = new QTimer( this ); m_timer = new QTimer( this );
connect( m_timer, SIGNAL( timeout() ), SLOT( checkQueries() ) ); connect( m_timer, SIGNAL( timeout() ), SLOT( checkQueries() ) );
@@ -193,7 +184,7 @@ WhatsHotWidget::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestDat
//ui->breadCrumbRight->setSelectionModel(selectionModelLeft); //ui->breadCrumbRight->setSelectionModel(selectionModelLeft);
//HACK ALERT - we want the second crumb to expand right away, so we //HACK ALERT - we want the second crumb to expand right away, so we
//force it here. We should find a more elegant want to do this //force it here. We should find a more elegant want to do this
ui->breadCrumbLeft->currentChangedTriggered(m_crumbModelLeft->index(0,0).child(0,0)); ui->breadCrumbLeft->currentChangedTriggered(m_crumbModelLeft->index(0,0).child(0,0).child(0,0));
break; break;
} }
case InfoSystem::InfoChart: case InfoSystem::InfoChart:
@@ -226,13 +217,15 @@ WhatsHotWidget::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestDat
foreach ( const Tomahawk::InfoSystem::ArtistAlbumPair& album, albums ) foreach ( const Tomahawk::InfoSystem::ArtistAlbumPair& album, albums )
{ {
qDebug() << "Getting album" << album.album << "By" << album.artist; qDebug() << "Getting album" << album.album << "By" << album.artist;
album_ptr albumPtr = Album::get( 0, album.album, Artist::get( album.artist ) ); album_ptr albumPtr = Album::get(Artist::get( album.artist, true ), album.album );
al << albumPtr;
if(!albumPtr.isNull())
al << albumPtr;
} }
qDebug() << "Adding albums to model"; qDebug() << "Adding albums to model";
m_albumsModel->addAlbums( al ); m_albumsModel->addAlbums( al );
qDebug() << "Added albums";
} }
else if( type == "tracks" ) else if( type == "tracks" )
@@ -290,7 +283,8 @@ WhatsHotWidget::leftCrumbIndexChanged( QModelIndex index )
Tomahawk::InfoSystem::InfoCriteriaHash criteria; Tomahawk::InfoSystem::InfoCriteriaHash criteria;
criteria.insert("chart_id", chartId); criteria.insert("chart_id", chartId);
criteria.insert("chart_source", index.data().toString()); /// Remember to lower the source!
criteria.insert("chart_source", index.data().toString().toLower());
Tomahawk::InfoSystem::InfoRequestData requestData; Tomahawk::InfoSystem::InfoRequestData requestData;
QVariantMap customData; QVariantMap customData;

View File

@@ -10,7 +10,7 @@
<height>513</height> <height>513</height>
</rect> </rect>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout"> <layout class="QVBoxLayout" name="verticalLayout_2">
<item> <item>
<widget class="HeaderBreadCrumb" name="breadCrumbLeft" native="true"/> <widget class="HeaderBreadCrumb" name="breadCrumbLeft" native="true"/>
</item> </item>
@@ -45,21 +45,17 @@
</layout> </layout>
</widget> </widget>
<widget class="QWidget" name="page2"> <widget class="QWidget" name="page2">
<layout class="QVBoxLayout" name="verticalLayout2"> <layout class="QVBoxLayout" name="verticalLayout">
<item> <item>
<layout class="QVBoxLayout" name="verticalLayout_2"/> <widget class="AlbumView" name="additionsView">
<property name="dragEnabled">
<widget class="AlbumView" name="albumsViewLeft"> <bool>true</bool>
<property name="minimumSize"> </property>
<size> <property name="selectionMode">
<width>320</width> <enum>QAbstractItemView::ExtendedSelection</enum>
<height>0</height>
</size>
</property> </property>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
</widget> </widget>