mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-03-20 15:59:42 +01:00
commit
442d1b2713
@ -110,6 +110,7 @@ set( libSources
|
||||
infosystem/infosystemworker.cpp
|
||||
infosystem/infoplugins/generic/echonestplugin.cpp
|
||||
infosystem/infoplugins/generic/lastfmplugin.cpp
|
||||
infosystem/infoplugins/generic/chartsplugin.cpp
|
||||
infosystem/infoplugins/generic/musixmatchplugin.cpp
|
||||
infosystem/infoplugins/generic/musicbrainzPlugin.cpp
|
||||
|
||||
@ -335,6 +336,7 @@ set( libHeaders
|
||||
infosystem/infosystemcache.h
|
||||
infosystem/infoplugins/generic/echonestplugin.h
|
||||
infosystem/infoplugins/generic/lastfmplugin.h
|
||||
infosystem/infoplugins/generic/chartsplugin.h
|
||||
infosystem/infoplugins/generic/musixmatchplugin.h
|
||||
infosystem/infoplugins/generic/musicbrainzPlugin.h
|
||||
|
||||
|
482
src/libtomahawk/infosystem/infoplugins/generic/chartsplugin.cpp
Normal file
482
src/libtomahawk/infosystem/infoplugins/generic/chartsplugin.cpp
Normal file
@ -0,0 +1,482 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Hugo Lindström <hugolm84@gmail.com>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "chartsplugin.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QSettings>
|
||||
#include <QCryptographicHash>
|
||||
#include <QNetworkConfiguration>
|
||||
#include <QNetworkReply>
|
||||
#include <QDomElement>
|
||||
|
||||
#include "album.h"
|
||||
#include "typedefs.h"
|
||||
#include "audio/audioengine.h"
|
||||
#include "tomahawksettings.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
#define CHART_URL "http://charts.tomahawk-player.org:10080/"
|
||||
//#define CHART_URL "http://localhost:8080/"
|
||||
#include <qjson/parser.h>
|
||||
#include <qjson/serializer.h>
|
||||
|
||||
using namespace Tomahawk::InfoSystem;
|
||||
|
||||
static QString
|
||||
md5( const QByteArray& src )
|
||||
{
|
||||
QByteArray const digest = QCryptographicHash::hash( src, QCryptographicHash::Md5 );
|
||||
return QString::fromLatin1( digest.toHex() ).rightJustified( 32, '0' );
|
||||
}
|
||||
|
||||
|
||||
ChartsPlugin::ChartsPlugin()
|
||||
: InfoPlugin()
|
||||
{
|
||||
|
||||
|
||||
/// Add resources here
|
||||
m_chartResources << "last.fm" << "billboard" << "itunes";
|
||||
m_supportedGetTypes << InfoChart << InfoChartCapabilities;
|
||||
|
||||
}
|
||||
|
||||
|
||||
ChartsPlugin::~ChartsPlugin()
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ChartsPlugin::namChangedSlot( QNetworkAccessManager *nam )
|
||||
{
|
||||
tDebug() << "ChartsPlugin: namChangedSLot";
|
||||
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
if( !nam )
|
||||
return;
|
||||
|
||||
m_nam = QWeakPointer< QNetworkAccessManager >( nam );
|
||||
|
||||
/// Then get each chart from resource
|
||||
if( !m_chartResources.isEmpty() && m_nam && m_chartTypes.isEmpty() ){
|
||||
tDebug() << "ChartsPlugin: InfoChart fetching possible resources";
|
||||
|
||||
foreach(QVariant resource, m_chartResources)
|
||||
{
|
||||
QUrl url = QUrl( QString( CHART_URL "source/%1" ).arg(resource.toString() ) );
|
||||
QNetworkReply* reply = m_nam.data()->get( QNetworkRequest( url ) );
|
||||
connect( reply, SIGNAL( finished() ), SLOT( chartTypes() ) );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ChartsPlugin::dataError( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ChartsPlugin::getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << requestData.caller;
|
||||
qDebug() << Q_FUNC_INFO << requestData.customData;
|
||||
|
||||
switch ( requestData.type )
|
||||
{
|
||||
|
||||
case InfoChart:
|
||||
fetchChart( requestId, requestData );
|
||||
break;
|
||||
|
||||
case InfoChartCapabilities:
|
||||
fetchChartCapabilities( requestId, requestData );
|
||||
break;
|
||||
default:
|
||||
dataError( requestId, requestData );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ChartsPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input )
|
||||
{
|
||||
Q_UNUSED( caller )
|
||||
Q_UNUSED( type)
|
||||
Q_UNUSED( input )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ChartsPlugin::fetchChart( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
|
||||
if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() )
|
||||
{
|
||||
dataError( requestId, requestData );
|
||||
return;
|
||||
}
|
||||
|
||||
InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
|
||||
|
||||
/// Each request needs to contain both a id and source
|
||||
if ( !hash.contains( "chart_id" ) && !hash.contains( "chart_source" ) )
|
||||
{
|
||||
dataError( requestId, requestData );
|
||||
return;
|
||||
|
||||
}
|
||||
/// Set the criterias for current chart
|
||||
criteria["chart_id"] = hash["chart_id"];
|
||||
criteria["chart_source"] = hash["chart_source"];
|
||||
|
||||
emit getCachedInfo( requestId, criteria, 0, requestData );
|
||||
}
|
||||
|
||||
void
|
||||
ChartsPlugin::fetchChartCapabilities( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() )
|
||||
{
|
||||
dataError( requestId, requestData );
|
||||
return;
|
||||
}
|
||||
|
||||
//InfoCriteriaHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
|
||||
|
||||
emit getCachedInfo( requestId, criteria, 0, requestData );
|
||||
}
|
||||
|
||||
void
|
||||
ChartsPlugin::notInCacheSlot( uint requestId, QHash<QString, QString> criteria, Tomahawk::InfoSystem::InfoRequestData requestData )
|
||||
{
|
||||
if ( !m_nam.data() )
|
||||
{
|
||||
tLog() << "Have a null QNAM, uh oh";
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
switch ( requestData.type )
|
||||
{
|
||||
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"] ) );
|
||||
qDebug() << Q_FUNC_INFO << "Getting chart url" << url;
|
||||
|
||||
QNetworkReply* reply = m_nam.data()->get( QNetworkRequest( url ) );
|
||||
reply->setProperty( "requestId", requestId );
|
||||
reply->setProperty( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData >( requestData ) );
|
||||
|
||||
connect( reply, SIGNAL( finished() ), SLOT( chartReturned() ) );
|
||||
return;
|
||||
}
|
||||
|
||||
case InfoChartCapabilities:
|
||||
{
|
||||
|
||||
QVariantMap result;
|
||||
|
||||
/// Itunes have alot of country specified charts,
|
||||
/// Get those for later use
|
||||
QList<QString> geos;
|
||||
foreach( QVariant type, m_chartTypes )
|
||||
{
|
||||
|
||||
if( type.toMap().value( "geo" ).isValid() )
|
||||
{
|
||||
geos.append( type.toMap().value( "geo" ).toString() );
|
||||
}
|
||||
}
|
||||
/// We only need a unique list
|
||||
geos = QSet<QString>::fromList(geos).toList();
|
||||
|
||||
foreach( QVariant chartResource, m_chartResources )
|
||||
{
|
||||
|
||||
QList<Chart> album_charts;
|
||||
QList<Chart> track_charts;
|
||||
QList<Chart> artist_charts;
|
||||
QVariantMap charts;
|
||||
|
||||
if( chartResource.toString() == "last.fm")
|
||||
{
|
||||
|
||||
track_charts.append( Chart( "chart.getTopTracks", "Top Tracks", "tracks" ) );
|
||||
track_charts.append( Chart( "chart.getLovedTracks", "Loved Tracks", "tracks" ) );
|
||||
track_charts.append( Chart( "chart.getHypedTracks", "Hyped Tracks", "tracks" ) );
|
||||
|
||||
artist_charts.append( Chart( "chart.getTopArtists", "Top Artists", "artists" ) );
|
||||
artist_charts.append( Chart( "chart.getHypedArtists", "Hyped Artists", "artists" ) );
|
||||
|
||||
charts.insert( "Tracks", QVariant::fromValue<QList<Chart> >( track_charts ) );
|
||||
charts.insert( "Artists", QVariant::fromValue<QList<Chart> >( artist_charts ) );
|
||||
|
||||
|
||||
}
|
||||
else if( chartResource.toString() == "itunes")
|
||||
{
|
||||
QVariantMap geoCharts;
|
||||
|
||||
foreach(QVariant country, geos)
|
||||
{
|
||||
QList<Chart> geoAlbum_charts;
|
||||
QList<Chart> geoTrack_charts;
|
||||
|
||||
foreach( QVariant type, m_chartTypes )
|
||||
{
|
||||
|
||||
/// Itunes supplys charts based on geo, create breadcrumb for each of them
|
||||
|
||||
if( type.toMap().value( "source" ).toString() == chartResource.toString()
|
||||
&& type.toMap().value( "geo" ).isValid() )
|
||||
{
|
||||
|
||||
if( type.toMap().value( "geo" ).toString() == country.toString() )
|
||||
{
|
||||
QString countryString = "Geo: " + type.toMap().value( "geo" ).toString().toUpper();
|
||||
|
||||
if( type.toMap().value( "type" ).toString() == "Album" )
|
||||
{
|
||||
geoAlbum_charts.append( Chart( type.toMap().value("id").toString(), type.toMap().value("name").toString() , "album" ) );
|
||||
geoCharts.insert( "Albums", QVariant::fromValue<QList<Chart> >( geoAlbum_charts ) );
|
||||
charts.insert( countryString, QVariant::fromValue<QVariantMap >( geoCharts ) );
|
||||
}
|
||||
|
||||
if( type.toMap().value( "type" ).toString() == "Track" )
|
||||
{
|
||||
|
||||
geoTrack_charts.append( Chart( type.toMap().value("id").toString(), type.toMap().value("name").toString(), "tracks" ) );
|
||||
geoCharts.insert( "Tracks", QVariant::fromValue<QList<Chart> >( geoTrack_charts ) );
|
||||
charts.insert( countryString, QVariant::fromValue<QVariantMap >( geoCharts ) );
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
/// Billboard, and maybe others
|
||||
foreach( QVariant type, m_chartTypes )
|
||||
{
|
||||
|
||||
/// Append each type to its parent source
|
||||
/// @todo Add chartType enum
|
||||
if( type.toMap().value( "source" ).toString() == chartResource.toString() )
|
||||
{
|
||||
if( type.toMap().value( "type" ).toString() == "Album" )
|
||||
{
|
||||
album_charts.append( Chart( type.toMap().value("id").toString(), type.toMap().value("name").toString(), "album" ) );
|
||||
charts.insert( "Albums", QVariant::fromValue<QList<Chart> >( album_charts ) );
|
||||
}
|
||||
|
||||
if( type.toMap().value( "type" ).toString() == "Track" )
|
||||
{
|
||||
track_charts.append( Chart( type.toMap().value("id").toString(), type.toMap().value("name").toString(), "tracks" ) );
|
||||
charts.insert( "Tracks", QVariant::fromValue<QList<Chart> >( track_charts ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @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();
|
||||
|
||||
/// Add the possible charts and its types to breadcrumb
|
||||
result.insert( chartName , QVariant::fromValue<QVariantMap>( charts ) );
|
||||
}
|
||||
emit info(
|
||||
requestId,
|
||||
requestData,
|
||||
result
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
tLog() << "Couldn't figure out what to do with this type of request after cache miss";
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ChartsPlugin::chartTypes()
|
||||
{
|
||||
/// Get possible chart type for specific chart source
|
||||
tDebug() << "ChartsPlugin: InfoChart types 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;
|
||||
}
|
||||
|
||||
/// Got types, append!
|
||||
foreach(QVariant chart, res.value( "charts" ).toMap() ){
|
||||
m_chartTypes.append(chart);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
ChartsPlugin::chartReturned()
|
||||
{
|
||||
|
||||
/// Chart request returned something! Woho
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
|
||||
QVariantMap returnedData;
|
||||
|
||||
if ( reply->error() == QNetworkReply::NoError )
|
||||
{
|
||||
QJson::Parser p;
|
||||
bool ok;
|
||||
QVariantMap res = p.parse( reply, &ok ).toMap();
|
||||
|
||||
if ( !ok )
|
||||
{
|
||||
tLog() << "Failed to parse json from chart lookup:" << p.errorString() << "On line" << p.errorLine();
|
||||
return;
|
||||
}
|
||||
|
||||
/// SO we have a result, parse it!
|
||||
QVariantList chartResponse = res.value( "list" ).toList();
|
||||
QList<ArtistTrackPair> top_tracks;
|
||||
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" )
|
||||
setChartType( Album );
|
||||
else if( res.value( "type" ).toString() == "Track" )
|
||||
setChartType( Track );
|
||||
else
|
||||
setChartType( None );
|
||||
|
||||
|
||||
foreach ( QVariant chartR, chartResponse )
|
||||
{
|
||||
QString title, artist, album;
|
||||
QVariantMap chartMap = chartR.toMap();
|
||||
|
||||
if( !chartMap.isEmpty() )
|
||||
{
|
||||
|
||||
title = chartMap.value( "track" ).toString();
|
||||
album = chartMap.value( "album" ).toString();
|
||||
artist = chartMap.value( "artist" ).toString();
|
||||
/// Maybe we can use rank later on, to display something nice
|
||||
/// rank = chartMap.value( "rank" ).toString();
|
||||
|
||||
if( chartType() == 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...
|
||||
{
|
||||
tLog() << "Didn't get an artist and album name from chart, not enough to build a query on. Aborting" << title << album << artist;
|
||||
|
||||
}else
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << album << artist;
|
||||
ArtistAlbumPair pair;
|
||||
pair.artist = artist;
|
||||
pair.album = album;
|
||||
top_albums << pair;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
pair.artist = artist;
|
||||
pair.track = title;
|
||||
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 )
|
||||
{
|
||||
tDebug() << "ChartsPlugin:" << "\tgot " << top_albums.size() << " albums";
|
||||
returnedData["albums"] = QVariant::fromValue( top_albums );
|
||||
returnedData["type"] = "albums";
|
||||
}
|
||||
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
||||
|
||||
emit info(
|
||||
reply->property( "requestId" ).toUInt(),
|
||||
requestData,
|
||||
returnedData
|
||||
);
|
||||
// TODO update cache
|
||||
|
||||
}else qDebug() << "Network error";
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,83 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Hugo Lindström <hugolm84@gmail.com>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ChartsPlugin_H
|
||||
#define ChartsPlugin_H
|
||||
|
||||
#include "infosystem/infosystem.h"
|
||||
#include "infosystem/infosystemworker.h"
|
||||
#include <QNetworkReply>
|
||||
#include <QObject>
|
||||
|
||||
class QNetworkReply;
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
namespace InfoSystem
|
||||
{
|
||||
|
||||
class ChartsPlugin : public InfoPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChartsPlugin();
|
||||
virtual ~ChartsPlugin();
|
||||
|
||||
enum ChartType {
|
||||
None = 0x00,
|
||||
Track = 0x01,
|
||||
Album = 0x02,
|
||||
Artist = 0x04
|
||||
|
||||
};
|
||||
void setChartType( ChartType type ) { m_chartType = type; }
|
||||
ChartType chartType() const { return m_chartType; }
|
||||
|
||||
public slots:
|
||||
void chartReturned();
|
||||
void chartTypes();
|
||||
void namChangedSlot( QNetworkAccessManager *nam );
|
||||
|
||||
protected slots:
|
||||
virtual void getInfo( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
virtual void notInCacheSlot( uint requestId, Tomahawk::InfoSystem::InfoCriteriaHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
virtual void pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type, QVariant data );
|
||||
|
||||
private:
|
||||
void fetchChart( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void fetchChartCapabilities( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void dataError( uint requestId, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
QVariantList m_chartResources;
|
||||
QVariantList m_chartTypes;
|
||||
QList<Chart> m_charts;
|
||||
ChartType m_chartType;
|
||||
|
||||
QVariantMap m_chartResult;
|
||||
bool chartHasReturned;
|
||||
QWeakPointer< QNetworkAccessManager > m_nam;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // ChartsPlugin_H
|
@ -416,32 +416,6 @@ LastFmPlugin::notInCacheSlot( uint requestId, QHash<QString, QString> criteria,
|
||||
return;
|
||||
}
|
||||
|
||||
case InfoChartCapabilities:
|
||||
{
|
||||
QList<Chart> track_charts;
|
||||
track_charts.append( Chart( "chart.getTopTracks", "Top Tracks", "tracks" ) );
|
||||
track_charts.append( Chart( "chart.getLovedTracks", "Loved Tracks", "tracks" ) );
|
||||
track_charts.append( Chart( "chart.getHypedTracks", "Hyped Tracks", "tracks" ) );
|
||||
|
||||
QList<Chart> artist_charts;
|
||||
artist_charts.append( Chart( "chart.getTopArtists", "Top Artists", "artists" ) );
|
||||
artist_charts.append( Chart( "chart.getHypedArtists", "Hyped Artists", "artists" ) );
|
||||
|
||||
QVariantMap charts;
|
||||
charts.insert( "Tracks", QVariant::fromValue<QList<Chart> >( track_charts ) );
|
||||
charts.insert( "Artists", QVariant::fromValue<QList<Chart> >( artist_charts ) );
|
||||
|
||||
QVariantMap result;
|
||||
result.insert( "Last.fm", QVariant::fromValue<QVariantMap>( charts ) );
|
||||
|
||||
emit info(
|
||||
requestId,
|
||||
requestData,
|
||||
result
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
case InfoArtistSimilars:
|
||||
{
|
||||
lastfm::Artist a( criteria["artist"] );
|
||||
@ -495,7 +469,7 @@ LastFmPlugin::notInCacheSlot( uint requestId, QHash<QString, QString> criteria,
|
||||
|
||||
default:
|
||||
{
|
||||
tLog() << "Couldn't figure out what to do with this type of request after cache miss";
|
||||
tLog() << Q_FUNC_INFO << "Couldn't figure out what to do with this type of request after cache miss";
|
||||
emit info( requestId, requestData, QVariant() );
|
||||
return;
|
||||
}
|
||||
|
@ -135,6 +135,11 @@ struct ArtistTrackPair {
|
||||
QString track;
|
||||
};
|
||||
|
||||
struct ArtistAlbumPair {
|
||||
QString artist;
|
||||
QString album;
|
||||
};
|
||||
|
||||
struct Chart {
|
||||
Chart(){}
|
||||
Chart(const QString _id, const QString _label, const QString _type) {
|
||||
@ -284,8 +289,10 @@ Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoGenericMap );
|
||||
Q_DECLARE_METATYPE( Tomahawk::InfoSystem::InfoCriteriaHash );
|
||||
Q_DECLARE_METATYPE( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache > );
|
||||
Q_DECLARE_METATYPE( Tomahawk::InfoSystem::ArtistTrackPair );
|
||||
Q_DECLARE_METATYPE( Tomahawk::InfoSystem::ArtistAlbumPair );
|
||||
Q_DECLARE_METATYPE( Tomahawk::InfoSystem::Chart );
|
||||
Q_DECLARE_METATYPE( QList<Tomahawk::InfoSystem::ArtistTrackPair> );
|
||||
Q_DECLARE_METATYPE( QList<Tomahawk::InfoSystem::ArtistAlbumPair> );
|
||||
Q_DECLARE_METATYPE( QList<Tomahawk::InfoSystem::Chart> );
|
||||
|
||||
#endif // TOMAHAWK_INFOSYSTEM_H
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "infosystemcache.h"
|
||||
#include "infoplugins/generic/echonestplugin.h"
|
||||
#include "infoplugins/generic/musixmatchplugin.h"
|
||||
#include "infoplugins/generic/chartsplugin.h"
|
||||
#include "infoplugins/generic/lastfmplugin.h"
|
||||
#include "infoplugins/generic/musicbrainzPlugin.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
@ -85,10 +86,16 @@ InfoSystemWorker::init( QWeakPointer< Tomahawk::InfoSystem::InfoSystemCache> cac
|
||||
InfoPluginPtr mbptr( new MusicBrainzPlugin() );
|
||||
m_plugins.append( mbptr );
|
||||
registerInfoTypes( mbptr, mbptr.data()->supportedGetTypes(), mbptr.data()->supportedPushTypes() );
|
||||
|
||||
InfoPluginPtr sptr( new ChartsPlugin() );
|
||||
m_plugins.append( sptr );
|
||||
registerInfoTypes( sptr, sptr.data()->supportedGetTypes(), sptr.data()->supportedPushTypes() );
|
||||
|
||||
InfoPluginPtr lfmptr( new LastFmPlugin() );
|
||||
m_plugins.append( lfmptr );
|
||||
registerInfoTypes( lfmptr, lfmptr.data()->supportedGetTypes(), lfmptr.data()->supportedPushTypes() );
|
||||
|
||||
|
||||
#ifdef Q_WS_MAC
|
||||
InfoPluginPtr admptr( new AdiumPlugin() );
|
||||
m_plugins.append( admptr );
|
||||
|
@ -53,12 +53,15 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent )
|
||||
{
|
||||
ui->setupUi( this );
|
||||
|
||||
ui->additionsView->setFrameShape( QFrame::NoFrame );
|
||||
ui->additionsView->setAttribute( Qt::WA_MacShowFocusRect, 0 );
|
||||
|
||||
TomahawkUtils::unmarginLayout( layout() );
|
||||
TomahawkUtils::unmarginLayout( ui->stackLeft->layout() );
|
||||
TomahawkUtils::unmarginLayout( ui->horizontalLayout->layout() );
|
||||
TomahawkUtils::unmarginLayout( ui->horizontalLayout_2->layout() );
|
||||
TomahawkUtils::unmarginLayout( ui->breadCrumbLeft->layout() );
|
||||
|
||||
TomahawkUtils::unmarginLayout( ui->verticalLayout->layout() );
|
||||
|
||||
//set crumb widgets
|
||||
SiblingCrumbButtonFactory * crumbFactory = new SiblingCrumbButtonFactory;
|
||||
@ -68,19 +71,15 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent )
|
||||
ui->breadCrumbLeft->setButtonFactory(crumbFactory);
|
||||
ui->breadCrumbLeft->setModel(m_crumbModelLeft);
|
||||
ui->breadCrumbLeft->setRootIcon(QIcon( RESPATH "images/charts.png" ));
|
||||
//ui->breadCrumbLeft->setSelectionModel(selectionModelLeft);
|
||||
ui->breadCrumbLeft->setUseAnimation(true);
|
||||
|
||||
connect(ui->breadCrumbLeft, SIGNAL(currentIndexChanged(QModelIndex)), SLOT(leftCrumbIndexChanged(QModelIndex)));
|
||||
|
||||
/*ui->breadCrumbRight->setButtonFactory(crumbFactory);
|
||||
ui->breadCrumbRight->setRootIcon(QIcon( RESPATH "images/charts.png" ));
|
||||
ui->breadCrumbRight->setModel(m_crumbModelLeft);
|
||||
ui->breadCrumbRight->setUseAnimation(true);*/
|
||||
|
||||
m_albumsModel = new AlbumModel( ui->additionsView );
|
||||
ui->additionsView->setAlbumModel( m_albumsModel );
|
||||
|
||||
m_tracksModel = new PlaylistModel( ui->tracksViewLeft );
|
||||
m_tracksModel->setStyle( TrackModel::Short );
|
||||
m_tracksModel->setStyle( TrackModel::ShortWithAvatars );
|
||||
|
||||
ui->tracksViewLeft->setFrameShape( QFrame::NoFrame );
|
||||
ui->tracksViewLeft->setAttribute( Qt::WA_MacShowFocusRect, 0 );
|
||||
@ -108,6 +107,7 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent )
|
||||
ui->artistsViewLeft->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
|
||||
ui->artistsViewLeft->header()->setVisible( false );
|
||||
|
||||
|
||||
m_timer = new QTimer( this );
|
||||
connect( m_timer, SIGNAL( timeout() ), SLOT( checkQueries() ) );
|
||||
|
||||
@ -118,8 +118,8 @@ WhatsHotWidget::WhatsHotWidget( QWidget* parent )
|
||||
|
||||
connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) );
|
||||
|
||||
|
||||
QTimer::singleShot( 0, this, SLOT( fetchData() ) );
|
||||
/// Itunes response is big, so maybe wait for it here?
|
||||
QTimer::singleShot( 1000, this, SLOT( fetchData() ) );
|
||||
}
|
||||
|
||||
|
||||
@ -184,7 +184,7 @@ WhatsHotWidget::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestDat
|
||||
//ui->breadCrumbRight->setSelectionModel(selectionModelLeft);
|
||||
//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
|
||||
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;
|
||||
}
|
||||
case InfoSystem::InfoChart:
|
||||
@ -206,6 +206,27 @@ WhatsHotWidget::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestDat
|
||||
foreach ( const QString& artist, artists )
|
||||
m_artistsModel->addArtists( Artist::get( artist ) );
|
||||
}
|
||||
else if( type == "albums" )
|
||||
{
|
||||
setLeftViewAlbums();
|
||||
m_albumsModel->clear();
|
||||
QList<album_ptr> al;
|
||||
const QList<Tomahawk::InfoSystem::ArtistAlbumPair> albums = returnedData["albums"].value<QList<Tomahawk::InfoSystem::ArtistAlbumPair> >();
|
||||
tDebug( LOGVERBOSE ) << "WhatsHot: got albums! " << albums.size();
|
||||
|
||||
foreach ( const Tomahawk::InfoSystem::ArtistAlbumPair& album, albums )
|
||||
{
|
||||
qDebug() << "Getting album" << album.album << "By" << album.artist;
|
||||
album_ptr albumPtr = Album::get(Artist::get( album.artist, true ), album.album );
|
||||
|
||||
if(!albumPtr.isNull())
|
||||
al << albumPtr;
|
||||
|
||||
}
|
||||
qDebug() << "Adding albums to model";
|
||||
m_albumsModel->addAlbums( al );
|
||||
|
||||
}
|
||||
else if( type == "tracks" )
|
||||
{
|
||||
setLeftViewTracks();
|
||||
@ -249,10 +270,20 @@ WhatsHotWidget::leftCrumbIndexChanged( QModelIndex index )
|
||||
return;
|
||||
|
||||
|
||||
QList<QModelIndex> indexes;
|
||||
while (index.parent().isValid())
|
||||
{
|
||||
indexes.prepend(index);
|
||||
index = index.parent();
|
||||
}
|
||||
|
||||
|
||||
const QString chartId = item->data().toString();
|
||||
|
||||
Tomahawk::InfoSystem::InfoCriteriaHash criteria;
|
||||
criteria.insert("chart_id", chartId);
|
||||
/// Remember to lower the source!
|
||||
criteria.insert("chart_source", index.data().toString().toLower());
|
||||
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData;
|
||||
QVariantMap customData;
|
||||
@ -325,6 +356,13 @@ WhatsHotWidget::parseNode(QStandardItem* parentItem, const QString &label, const
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WhatsHotWidget::setLeftViewAlbums()
|
||||
{
|
||||
ui->stackLeft->setCurrentIndex(2);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WhatsHotWidget::setLeftViewArtists()
|
||||
{
|
||||
|
@ -37,6 +37,7 @@ class TreeModel;
|
||||
class PlaylistModel;
|
||||
class OverlayWidget;
|
||||
class TreeProxyModel;
|
||||
class AlbumModel;
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
@ -83,7 +84,10 @@ private slots:
|
||||
|
||||
private:
|
||||
void setLeftViewArtists();
|
||||
void setLeftViewAlbums();
|
||||
void setLeftViewTracks();
|
||||
|
||||
|
||||
QStandardItem* parseNode( QStandardItem* parentItem, const QString &label, const QVariant &data );
|
||||
Ui::WhatsHotWidget *ui;
|
||||
|
||||
@ -91,6 +95,7 @@ private:
|
||||
TreeModel* m_artistsModel;
|
||||
TreeProxyModel* m_artistsProxy;
|
||||
QStandardItemModel* m_crumbModelLeft;
|
||||
AlbumModel* m_albumsModel;
|
||||
|
||||
QTimer* m_timer;
|
||||
};
|
||||
|
@ -10,7 +10,7 @@
|
||||
<height>513</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="HeaderBreadCrumb" name="breadCrumbLeft" native="true"/>
|
||||
</item>
|
||||
@ -44,20 +44,39 @@
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page2">
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="AlbumView" name="additionsView">
|
||||
<property name="dragEnabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionMode">
|
||||
<enum>QAbstractItemView::ExtendedSelection</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>PlaylistView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>playlist/playlistview.h</header>
|
||||
<class>AlbumView</class>
|
||||
<extends>QListView</extends>
|
||||
<header location="global">playlist/albumview.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ArtistView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header location="global">artistview.h</header>
|
||||
<header>artistview.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>PlaylistView</class>
|
||||
<extends>QTreeView</extends>
|
||||
<header>playlist/playlistview.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>HeaderBreadCrumb</class>
|
||||
|
@ -407,7 +407,9 @@ TomahawkApp::registerMetaTypes()
|
||||
|
||||
qRegisterMetaType< DirLister::Mode >("DirLister::Mode");
|
||||
qRegisterMetaType< Tomahawk::InfoSystem::ArtistTrackPair >("Tomahawk::InfoSystem::ArtistTrackPair");
|
||||
qRegisterMetaType< Tomahawk::InfoSystem::ArtistAlbumPair >("Tomahawk::InfoSystem::ArtistAlbumPair");
|
||||
qRegisterMetaType< QList<Tomahawk::InfoSystem::ArtistTrackPair> >("QList<Tomahawk::InfoSystem::ArtistTrackPair>");
|
||||
qRegisterMetaType< QList<Tomahawk::InfoSystem::ArtistAlbumPair> >("QList<Tomahawk::InfoSystem::ArtistAlbumPair>");
|
||||
qRegisterMetaType< Tomahawk::InfoSystem::Chart>("Tomahawk::InfoSystem::Chart");
|
||||
qRegisterMetaType< QList<Tomahawk::InfoSystem::Chart> >("QList<Tomahawk::InfoSystem::Chart>");
|
||||
qRegisterMetaType< QPersistentModelIndex >( "QPersistentModelIndex" );
|
||||
|
Loading…
x
Reference in New Issue
Block a user