mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-03-24 09:49:42 +01:00
Implement New Releases info plugin
Heavily based off existing charts info plugin, refactoring and consolidating can be done later.
This commit is contained in:
parent
066c387ae9
commit
69d1450b5c
@ -251,6 +251,7 @@ set( libSources
|
||||
|
||||
infosystem/infoplugins/generic/echonestplugin.cpp
|
||||
infosystem/infoplugins/generic/chartsplugin.cpp
|
||||
infosystem/infoplugins/generic/newreleasesplugin.cpp
|
||||
infosystem/infoplugins/generic/spotifyPlugin.cpp
|
||||
infosystem/infoplugins/generic/hypemPlugin.cpp
|
||||
infosystem/infoplugins/generic/musixmatchplugin.cpp
|
||||
|
@ -0,0 +1,343 @@
|
||||
#include "newreleasesplugin.h"
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QSettings>
|
||||
#include <QtNetwork/QNetworkConfiguration>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
|
||||
#include "album.h"
|
||||
#include "chartsplugin_data_p.h"
|
||||
#include "typedefs.h"
|
||||
#include "audio/audioengine.h"
|
||||
#include "tomahawksettings.h"
|
||||
#include "utils/tomahawkutils.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
#include <qjson/parser.h>
|
||||
#include <qjson/serializer.h>
|
||||
|
||||
#define CHART_URL "http://charts.tomahawk-player.org/"
|
||||
//#define CHART_URL "http://localhost:8080/"
|
||||
|
||||
using namespace Tomahawk::InfoSystem;
|
||||
|
||||
NewReleasesPlugin::NewReleasesPlugin()
|
||||
: InfoPlugin()
|
||||
, m_nrFetchJobs ( 0 )
|
||||
{
|
||||
m_nrVersion = "0";
|
||||
m_supportedGetTypes << InfoNewReleaseCapabilities << InfoNewRelease;
|
||||
}
|
||||
|
||||
NewReleasesPlugin::~NewReleasesPlugin()
|
||||
{
|
||||
tDebug ( LOGVERBOSE ) << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
void NewReleasesPlugin::dataError ( InfoRequestData requestData )
|
||||
{
|
||||
emit info ( requestData, QVariant() );
|
||||
return;
|
||||
}
|
||||
|
||||
void NewReleasesPlugin::getInfo ( InfoRequestData requestData )
|
||||
{
|
||||
//qDebug() << Q_FUNC_INFO << requestData.caller;
|
||||
//qDebug() << Q_FUNC_INFO << requestData.customData;
|
||||
|
||||
InfoStringHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >();
|
||||
bool foundSource = false;
|
||||
|
||||
switch ( requestData.type ) {
|
||||
case InfoNewRelease:
|
||||
/// We need something to check if the request is actually ment to go to this plugin
|
||||
if ( !hash.contains ( "nr_source" ) ) {
|
||||
tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "Hash did not contain required param!";
|
||||
dataError ( requestData );
|
||||
break;
|
||||
} else {
|
||||
foreach ( QString resource, m_nrSources ) {
|
||||
if ( resource == hash["nr_source"] ) {
|
||||
foundSource = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !foundSource ) {
|
||||
dataError ( requestData );
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
fetchNRFromCache ( requestData );
|
||||
break;
|
||||
|
||||
case InfoNewReleaseCapabilities:
|
||||
fetchNRCapabilitiesFromCache ( requestData );
|
||||
break;
|
||||
default:
|
||||
dataError ( requestData );
|
||||
}
|
||||
}
|
||||
|
||||
void NewReleasesPlugin::fetchNRFromCache ( InfoRequestData requestData )
|
||||
{
|
||||
if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) {
|
||||
dataError ( requestData );
|
||||
return;
|
||||
}
|
||||
|
||||
InfoStringHash hash = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >();
|
||||
Tomahawk::InfoSystem::InfoStringHash criteria;
|
||||
|
||||
/// Each request needs to contain both a id and source
|
||||
if ( !hash.contains ( "nr_id" ) && !hash.contains ( "nr_source" ) ) {
|
||||
tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "Hash did not contain required params!";
|
||||
dataError ( requestData );
|
||||
return;
|
||||
|
||||
}
|
||||
/// Set the criterias for current chart
|
||||
criteria["nr_id"] = hash["nr_id"];
|
||||
criteria["nr_source"] = hash["nr_source"];
|
||||
|
||||
emit getCachedInfo ( criteria, 86400000, requestData );
|
||||
}
|
||||
|
||||
void NewReleasesPlugin::fetchNRCapabilitiesFromCache ( InfoRequestData requestData )
|
||||
{
|
||||
if ( !requestData.input.canConvert< Tomahawk::InfoSystem::InfoStringHash >() ) {
|
||||
tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "Could not convert requestData to InfoStringHash!";
|
||||
dataError ( requestData );
|
||||
return;
|
||||
}
|
||||
|
||||
Tomahawk::InfoSystem::InfoStringHash criteria;
|
||||
criteria[ "InfoNewReleaseCapabilities" ] = "newreleasesplugin";
|
||||
criteria[ "InfoNewReleaseVersion" ] = m_nrVersion;
|
||||
emit getCachedInfo ( criteria, 864000000, requestData );
|
||||
}
|
||||
|
||||
void NewReleasesPlugin::notInCacheSlot ( InfoStringHash criteria, InfoRequestData requestData )
|
||||
{
|
||||
switch ( requestData.type ) {
|
||||
case InfoNewRelease: {
|
||||
tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "InfoNewRelease not in cache! Fetching...";
|
||||
fetchNR ( requestData, criteria["nr_source"], criteria["nr_id"] );
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
case InfoNewReleaseCapabilities: {
|
||||
tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "InfoChartCapabilities not in cache! Fetching...";
|
||||
fetchNRSourcesList();
|
||||
m_cachedRequests.append ( requestData );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
default: {
|
||||
tLog() << Q_FUNC_INFO << "Couldn't figure out what to do with this type of request after cache miss";
|
||||
emit info ( requestData, QVariant() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NewReleasesPlugin::fetchNRSourcesList()
|
||||
{
|
||||
QUrl url = QUrl ( QString ( CHART_URL "newreleases" ) );
|
||||
QNetworkReply* reply = TomahawkUtils::nam()->get ( QNetworkRequest ( url ) );
|
||||
|
||||
tDebug() << "fetching:" << url;
|
||||
connect ( reply, SIGNAL ( finished() ), SLOT ( nrSourcesList() ) );
|
||||
|
||||
}
|
||||
|
||||
void NewReleasesPlugin::nrSourcesList()
|
||||
{
|
||||
tDebug ( LOGVERBOSE ) << "Got newreleases sources list";
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*> ( sender() );
|
||||
|
||||
if ( reply->error() == QNetworkReply::NoError ) {
|
||||
QJson::Parser p;
|
||||
bool ok;
|
||||
const QVariantMap res = p.parse ( reply, &ok ).toMap();
|
||||
const QVariantList sources = res.value ( "sources" ).toList();
|
||||
|
||||
if ( !ok ) {
|
||||
tLog() << "Failed to parse sources" << p.errorString() << "On line" << p.errorLine();
|
||||
return;
|
||||
}
|
||||
|
||||
m_nrSources.clear();
|
||||
foreach ( const QVariant &source, sources ) {
|
||||
m_nrSources << source.toString();
|
||||
}
|
||||
|
||||
fetchAllNRSources();
|
||||
}
|
||||
}
|
||||
|
||||
void NewReleasesPlugin::fetchAllNRSources()
|
||||
{
|
||||
if ( !m_nrSources.isEmpty() && m_allNRsMap.isEmpty() ) {
|
||||
tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "InfoNewRelease fetching source data";
|
||||
foreach ( QString source, m_nrSources ) {
|
||||
QUrl url = QUrl ( QString ( CHART_URL "newreleases/%1" ).arg ( source ) );
|
||||
QNetworkReply* reply = TomahawkUtils::nam()->get ( QNetworkRequest ( url ) );
|
||||
reply->setProperty ( "nr_source", source );
|
||||
|
||||
tDebug() << "fetching:" << url;
|
||||
connect ( reply, SIGNAL ( finished() ), SLOT ( nrList() ) );
|
||||
|
||||
m_nrFetchJobs++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void NewReleasesPlugin::fetchNR ( InfoRequestData requestData, const QString& source, const QString& nr_id )
|
||||
{
|
||||
/// Fetch the chart, we need source and id
|
||||
QUrl url = QUrl ( QString ( CHART_URL "newreleases/%1/%2" ).arg ( source ).arg ( nr_id ) );
|
||||
tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "fetching: " << url;
|
||||
|
||||
QNetworkReply* reply = TomahawkUtils::nam()->get ( QNetworkRequest ( url ) );
|
||||
reply->setProperty ( "requestData", QVariant::fromValue< Tomahawk::InfoSystem::InfoRequestData > ( requestData ) );
|
||||
|
||||
connect ( reply, SIGNAL ( finished() ), SLOT ( nrReturned() ) );
|
||||
}
|
||||
|
||||
void NewReleasesPlugin::nrList()
|
||||
{
|
||||
tDebug ( LOGVERBOSE ) << "Got newreleases list result";
|
||||
QNetworkReply* reply = qobject_cast<QNetworkReply*> ( sender() );
|
||||
|
||||
if ( reply->error() == QNetworkReply::NoError ) {
|
||||
QJson::Parser p;
|
||||
bool ok;
|
||||
const QVariantMap res = p.parse ( reply, &ok ).toMap();
|
||||
|
||||
if ( !ok ) {
|
||||
tLog() << "Failed to parse resources" << p.errorString() << "On line" << p.errorLine();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/// Got types, append!
|
||||
const QString source = reply->property ( "nr_source" ).toString();
|
||||
|
||||
// We'll populate newreleases with the data from the server
|
||||
QVariantMap newreleases;
|
||||
QString nrName;
|
||||
|
||||
// Building:
|
||||
// [Source] - New Release
|
||||
QList< InfoStringHash > albumNRs;
|
||||
|
||||
foreach ( const QVariant &nrObj, res.values() ) {
|
||||
if ( !nrObj.toMap().isEmpty() ) {
|
||||
const QVariantMap nrMap = nrObj.toMap();
|
||||
const QString type = nrMap.value ( "type" ).toString();
|
||||
|
||||
InfoStringHash nr;
|
||||
nr["id"] = nrMap.value ( "id" ).toString();
|
||||
nr["label"] = nrMap.value ( "name" ).toString();
|
||||
nr["date"] = nrMap.value ( "date" ).toString();
|
||||
|
||||
if ( type == "Album" ) {
|
||||
nr[ "type" ] = "album";
|
||||
albumNRs.append ( nr );
|
||||
} else {
|
||||
tLog() << "Unknown newrelease type " << type;
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if ( !albumNRs.isEmpty() )
|
||||
newreleases.insert ( tr ( "Albums" ), QVariant::fromValue< QList< Tomahawk::InfoSystem::InfoStringHash > > ( albumNRs ) );
|
||||
|
||||
/// @note For displaying purposes, upper the first letter
|
||||
/// @note Remeber to lower it when fetching this!
|
||||
nrName = source;
|
||||
nrName[0] = nrName[0].toUpper();
|
||||
|
||||
tDebug ( LOGVERBOSE ) << Q_FUNC_INFO << "ADDING newrelease TO NRS:" << nrName;
|
||||
QVariantMap defaultMap = m_allNRsMap.value ( "defaults" ).value< QVariantMap >();
|
||||
m_allNRsMap.insert ( nrName, QVariant::fromValue< QVariantMap > ( newreleases ) );
|
||||
|
||||
} else {
|
||||
tLog() << "Error fetching charts:" << reply->errorString();
|
||||
}
|
||||
|
||||
m_nrFetchJobs--;
|
||||
if ( !m_cachedRequests.isEmpty() && m_nrFetchJobs == 0 ) {
|
||||
foreach ( InfoRequestData request, m_cachedRequests ) {
|
||||
emit info ( request, m_allNRsMap );
|
||||
// update cache
|
||||
Tomahawk::InfoSystem::InfoStringHash criteria;
|
||||
criteria[ "InfoNewReleaseCapabilities" ] = "newreleasesplugin";
|
||||
criteria[ "InfoNewReleaseVersion" ] = m_nrVersion;
|
||||
emit updateCache ( criteria, 864000000, request.type, m_allNRsMap );
|
||||
}
|
||||
m_cachedRequests.clear();
|
||||
}
|
||||
}
|
||||
|
||||
void NewReleasesPlugin::nrReturned()
|
||||
{
|
||||
/// 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 albumList = res.value ( "list" ).toList();
|
||||
QList< Tomahawk::InfoSystem::InfoStringHash > newreleases;
|
||||
|
||||
foreach( const QVariant & albumObj, albumList ) {
|
||||
QVariantMap albumMap = albumObj.toMap();
|
||||
if(!albumMap.isEmpty()) {
|
||||
const QString album = albumMap.value("album").toString();
|
||||
const QString artist = albumMap.value("artist").toString();
|
||||
const QString date = albumMap.value("date").toString();
|
||||
|
||||
Tomahawk::InfoSystem::InfoStringHash pair;
|
||||
pair["artist"] = artist;
|
||||
pair["album"] = album;
|
||||
newreleases.append( pair );
|
||||
}
|
||||
}
|
||||
|
||||
tDebug() << "NewReleasesPlugin:" << "\tgot " << newreleases.size() << " albums";
|
||||
returnedData[ "albums" ] = QVariant::fromValue< QList< Tomahawk::InfoSystem::InfoStringHash > >( newreleases );
|
||||
returnedData[ "type" ] = "albums";
|
||||
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
|
||||
|
||||
emit info( requestData, returnedData );
|
||||
// update cache
|
||||
Tomahawk::InfoSystem::InfoStringHash criteria;
|
||||
Tomahawk::InfoSystem::InfoStringHash origData = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >();
|
||||
criteria[ "nr_id" ] = origData[ "nr_id" ];
|
||||
criteria[ "nr_source" ] = origData[ "nr_source" ];
|
||||
emit updateCache( criteria, 86400000, requestData.type, returnedData );
|
||||
} else
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Network error in fetching newrelease:" << reply->url().toString();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,100 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2012, Casey Link <unnamedrambler@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 NEWRELEASESPLUGIN_H
|
||||
#define NEWRELEASESPLUGIN_H
|
||||
|
||||
#include "infosystem/infosystem.h"
|
||||
#include "infosystem/infosystemworker.h"
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
#include <QtCore/QObject>
|
||||
|
||||
class QNetworkReply;
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
namespace InfoSystem
|
||||
{
|
||||
|
||||
class NewReleasesPlugin : public InfoPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
NewReleasesPlugin();
|
||||
virtual ~NewReleasesPlugin();
|
||||
|
||||
protected slots:
|
||||
virtual void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
virtual void notInCacheSlot( Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
virtual void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
|
||||
{
|
||||
Q_UNUSED( pushData );
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a QNetworkReply of a list of newreleases sources.
|
||||
*/
|
||||
void nrSourcesList();
|
||||
|
||||
/**
|
||||
* Parses a QNetworkReply of a list of newreleases from a particular source
|
||||
*/
|
||||
void nrList();
|
||||
|
||||
/**
|
||||
* Parses a QNetworkReply for the newreleases data for a particular newrelease
|
||||
*/
|
||||
void nrReturned();
|
||||
|
||||
private:
|
||||
/**
|
||||
* Fetch list of newlreeases sources (e.g., rovi)
|
||||
* Populates the m_nrSources member.
|
||||
*/
|
||||
void fetchNRSourcesList();
|
||||
/**
|
||||
* Requests newrelease list for each source in m_chartSources
|
||||
*/
|
||||
void fetchAllNRSources();
|
||||
/**
|
||||
* Fetches a specific newrelease from a particular source.
|
||||
* Updates the cache.
|
||||
*/
|
||||
void fetchNR( Tomahawk::InfoSystem::InfoRequestData requestData, const QString& source, const QString& nr_id );
|
||||
void fetchNRFromCache( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void fetchNRCapabilitiesFromCache( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void dataError( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
|
||||
QStringList m_nrSources;
|
||||
QString m_nrVersion;
|
||||
QList< InfoStringHash > m_newreleases;
|
||||
//ChartType m_chartType;
|
||||
QVariantMap m_allNRsMap;
|
||||
uint m_nrFetchJobs;
|
||||
QList< InfoRequestData > m_cachedRequests;
|
||||
QHash< QString, QString > m_cachedCountries;
|
||||
QWeakPointer< QNetworkAccessManager > m_nam;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // NEWRELEASESPLUGIN_H
|
@ -112,6 +112,9 @@ enum InfoType { // as items are saved in cache, mark them here to not change the
|
||||
*/
|
||||
InfoChart = 51,
|
||||
|
||||
InfoNewReleaseCapabilities = 52,
|
||||
InfoNewRelease = 53,
|
||||
|
||||
InfoMiscTopHotttness = 60,
|
||||
InfoMiscTopTerms = 61,
|
||||
|
||||
@ -195,7 +198,7 @@ struct InfoPushData {
|
||||
, pushFlags( pflags )
|
||||
, infoPair( Tomahawk::InfoSystem::PushInfoPair( QVariantMap(), QVariant() ) )
|
||||
{}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "infoplugins/generic/echonestplugin.h"
|
||||
#include "infoplugins/generic/musixmatchplugin.h"
|
||||
#include "infoplugins/generic/chartsplugin.h"
|
||||
#include "infoplugins/generic/newreleasesplugin.h"
|
||||
#include "infoplugins/generic/spotifyPlugin.h"
|
||||
#include "infoplugins/generic/musicbrainzPlugin.h"
|
||||
#include "infoplugins/generic/hypemPlugin.h"
|
||||
@ -86,6 +87,7 @@ InfoSystemWorker::init( Tomahawk::InfoSystem::InfoSystemCache* cache )
|
||||
addInfoPlugin( InfoPluginPtr( new MusixMatchPlugin() ) );
|
||||
addInfoPlugin( InfoPluginPtr( new MusicBrainzPlugin() ) );
|
||||
addInfoPlugin( InfoPluginPtr( new ChartsPlugin() ) );
|
||||
addInfoPlugin( InfoPluginPtr( new NewReleasesPlugin() ) );
|
||||
addInfoPlugin( InfoPluginPtr( new RoviPlugin() ) );
|
||||
addInfoPlugin( InfoPluginPtr( new SpotifyPlugin() ) );
|
||||
addInfoPlugin( InfoPluginPtr( new hypemPlugin() ) );
|
||||
@ -274,7 +276,7 @@ void
|
||||
InfoSystemWorker::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "type is " << pushData.type;
|
||||
|
||||
|
||||
if ( pushData.pushFlags != PushNoFlag )
|
||||
{
|
||||
if ( pushData.pushFlags & PushShortUrlFlag )
|
||||
@ -334,7 +336,7 @@ InfoSystemWorker::shortLinkReady( QUrl longUrl, QUrl shortUrl, QVariant callback
|
||||
m_shortLinksWaiting--;
|
||||
if ( !m_shortLinksWaiting )
|
||||
disconnect( GlobalActionManager::instance(), SIGNAL( shortLinkReady( QUrl, QUrl, QVariant ) ) );
|
||||
|
||||
|
||||
if ( !callbackObj.isValid() )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "callback object was not valid, cannot continue";
|
||||
|
Loading…
x
Reference in New Issue
Block a user