Commit f47a7ca9 authored by Zack Rusin's avatar Zack Rusin

Adding MusicBrainz support :)

I still have to integrate them with tag guesser but take a loot at those
classes and the test.

svn path=/trunk/kdemultimedia/juk/; revision=224147
parent d3a2febe
bin_PROGRAMS = juk
check_PROGRAMS = tagguessertest
check_PROGRAMS = tagguessertest mbtest
juk_SOURCES = directorylistbase.ui genrelisteditorbase.ui \
gstreamerplayer.cpp artsplayer.cpp directorylist.cpp stringhash.cpp \
......@@ -11,9 +11,11 @@ juk_SOURCES = directorylistbase.ui genrelisteditorbase.ui \
slideraction.cpp keydialog.cpp juk.cpp main.cpp tagguesser.cpp \
tagguesserconfigdlgwidget.ui tagguesserconfigdlg.cpp jukIface.skel \
playlistsearch.cpp searchwidget.cpp filerenamer.cpp dynamicplaylist.cpp \
searchplaylist.cpp
searchplaylist.cpp musicbrainzquery.cpp
tagguessertest_SOURCES = tagguessertest.cpp tagguesser.cpp
mbtest_SOURCES = mbtest.cpp musicbrainzquery.cpp
INCLUDES= $(all_includes) -I$(arts_includes)
......@@ -25,12 +27,23 @@ gstlibs = -lkdegst -lkdegstplay
endif
##################################################
juk_LDADD = $(gstlibs) -lid3 -lsoundserver_idl $(LIB_KIO)
##################################################
# check to see if MusicBrainz is available
##################################################
if link_lib_MB
mblibs = -lmusicbrainz
endif
##################################################
juk_LDADD = $(gstlibs) $(mblibs) -lid3 -lsoundserver_idl $(LIB_KIO)
juk_LDFLAGS = $(all_libraries) $(KDE_RPATH)
tagguessertest_LDADD = $(LIB_KDECORE)
tagguessertest_LDFLAGS = $(all_libraries)
mbtest_LDADD = $(LIB_KDECORE) $(mblibs)
mbtest_LDFLAGS = $(all_libraries)
SUBDIRS = pics data
rcdir = $(kde_datadir)/juk
......
......@@ -24,3 +24,15 @@ if test "x$have_gst" == "xfalse"; then
echo "*"
echo "**************************************************"
fi
if test "x$have_musicbrainz" == "xfalse"; then
echo "**************************************************"
echo "*"
echo "* You do not seem to have libmusicbrainz and JuK"
echo "* will be compiled without MusicBrainz support "
echo "* Automatic song recogntion will not be supported. "
echo "* Please download libmusicbrainz 2.0.1 from "
echo "* http://www.musicbrainz.org/products/client/download.html "
echo "*"
echo "**************************************************"
fi
......@@ -32,4 +32,32 @@ KDE_CHECK_HEADER(kde/gst/gstreamer.h,
AC_NO_GST
)
AC_DEFUN(AC_HAVE_MUSICBRAINZ,
[
AC_DEFINE(HAVE_MUSICBRAINZ, 1, [have MusicBrainz])
have_musicbrainz=true
])
AC_DEFUN(AC_NO_MUSICBRAINZ,
[
AC_DEFINE(HAVE_MUSICBRAINZ, 0, [have MusicBrainz])
have_musicbrainz=false
])
KDE_CHECK_HEADER(musicbrainz/musicbrainz.h,
AC_HAVE_MUSICBRAINZ,
AC_NO_MUSICBRAINZ
)
KDE_FIND_PATH(trm,TRM,[$kde_default_bindirs],[
AC_MSG_WARN([Could not find trm utility anywhere, check http://www.musicbrainz.org/products/trmgen/download.html for TRM Generator.])
])
if test -z "$TRM" ; then
AC_DEFINE(HAVE_TRM,0,[Is trm program present])
else
AC_DEFINE(HAVE_TRM,1,[Is trm program present])
fi
AM_CONDITIONAL(link_lib_GST, test x$have_gst = xtrue)
AM_CONDITIONAL(link_lib_MB, test x$have_musicbrainz = xtrue)
//Zack - Pizza license - you agree to eat pizza if you modify this file.
//Compile with :
//g++ -Wall -g -lmusicbrainz -L$QTDIR/lib -L$KDEDIR/lib -I$QTDIR/include -I$KDEDIR/include -lqt-mt -lkdecore musicbrainzquery.cpp mbtest.cpp -o mbtest
//First create mocs of course:
//moc mbtest.cpp -o mbtest.moc
//moc musicbrainzquery.h -o musicbrainzquery.moc
//then "./test some_file.mp3" will identify (or at least try to) the file
#include <kapplication.h>
#include <kdebug.h>
#include <qobject.h>
#include "musicbrainzquery.h"
class TestMB : public QObject {
Q_OBJECT
public:
TestMB( const QString& file ) : QObject(0, "hello") {
QStringList l;
l<<file;
MusicBrainzQuery *query = new MusicBrainzQuery( MusicBrainzQuery::File ,
l );
connect( query, SIGNAL(done(const MusicBrainzQuery::TrackList&)),
SLOT(slotTrack(const MusicBrainzQuery::TrackList&)) );
query->start();
}
public slots:
void slotTrack( const MusicBrainzQuery::TrackList& res ) {
for( MusicBrainzQuery::TrackList::ConstIterator itr = res.begin();
itr != res.end(); ++itr ) {
kdDebug() <<"Album = "<< (*itr).album <<endl;
kdDebug() <<"Artist = "<< (*itr).artist << endl;
kdDebug() <<"Id = "<< (*itr).id <<endl;
kdDebug() <<"Name = "<< (*itr).name <<endl;
kdDebug() <<"Artist id = "<< (*itr).artistId <<endl;
kdDebug() <<"Song Num = "<< (*itr).num <<endl;
}
kapp->quit();
}
};
#include "mbtest.moc"
int
main( int argc, char **argv )
{
KApplication app( argc, argv, "test" );
if ( argc != 2 ) {
kdDebug()<<"Usage = "<<argv[0]<<" some_file.mp3"<<endl;
exit(1);
}
TestMB mb(argv[1]);
return app.exec();
}
// musicbrainzquery.cpp
//
// Copyright (C) 2003 Zack Rusin <zack@kde.org>
//
// This program 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 2
// of the License, or (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
#include "../config.h"
#if HAVE_MUSICBRAINZ
#include "musicbrainzquery.h"
#include <kprocess.h>
#include <kdebug.h>
#include <qtimer.h>
#include <qvaluelist.h>
#include <string>
#include <vector>
MusicBrainzQuery::MusicBrainzQuery(QueryType query, QStringList args,
QObject* parent, const char* name)
: QObject(parent,name), m_query(query), m_arguments(args), m_tracks(false)
{
}
void MusicBrainzQuery::start()
{
if (m_query == File){
#if HAVE_TRM
KProcess *proc = new KProcess(this);
*proc << "trm";
*proc << m_arguments.first();
connect(proc, SIGNAL(receivedStdout(KProcess*, char*, int)),
SLOT(trmData(KProcess*, char*, int)));
connect(proc, SIGNAL(processExited(KProcess *)),
SLOT(trmGenerationFinished(KProcess *)));
proc->start(KProcess::NotifyOnExit, KProcess::AllOutput);
#else
emit done(TrackList());
#endif
} else
QTimer::singleShot(0, this, SLOT(slotQuery()));
}
void MusicBrainzQuery::slotQuery()
{
std::string queryString;
std::string resultString;
std::string extractString;
AlbumList albums;
TrackList tracks;
std::vector<std::string> vec;
queryStrings(queryString, resultString, extractString);
//UseUTF8( false );
SetDepth( 4 );
for(QStringList::Iterator itr = m_arguments.begin();
itr != m_arguments.end(); ++itr) {
vec.push_back(std::string((*itr).latin1()));
}
bool ret = Query(queryString, &vec);
if( ret ) {
std::string temp;
int numEntries = DataInt(resultString);
for( int i = 1; i <= numEntries; ++i ) {
Select(extractString, i);
if ( m_tracks ) {
Track track(extractTrack(i));
tracks.append(track);
} else {
Album alb(extractAlbum(i));
albums.append(alb);
}
}
} else {
std::string error;
GetQueryError(error);
kdDebug()<<"Query failed: "<< error.c_str() <<endl;
}
if (m_tracks)
emit done(tracks);
else
emit done(albums);
deleteLater();//schedule deletion
}
QString MusicBrainzQuery::dataExtract(const QString& type, int i)
{
std::string str = Data(type.latin1(), i);
if (str.empty()) {
return QString::null;
} else {
return str.c_str();
}
}
void MusicBrainzQuery::queryStrings(std::string& query, std::string& result, std::string& extraction)
{
switch(m_query) {
case CD:
query = MBQ_GetCDInfo;
result = MBE_GetNumAlbums;
extraction = MBS_SelectAlbum;
break;
case TrackFromTRM:
query = MBQ_TrackInfoFromTRMId;
result = MBE_GetNumTracks;
extraction = MBS_SelectTrack;
m_tracks = true;
break;
case TrackFromID:
query = MBQ_QuickTrackInfoFromTrackId;
result = MBE_GetNumTracks;
extraction = MBS_SelectTrack;
m_tracks = true;
break;
case ArtistByName:
query = MBQ_FindArtistByName;
result = MBE_GetNumArtists;
extraction = MBS_SelectArtist ;
break;
case AlbumByName:
query = MBQ_FindAlbumByName;
result = MBE_GetNumAlbums;
extraction = MBS_SelectAlbum ;
break;
case TrackByName:
query = MBQ_FindTrackByName;
result = MBE_GetNumTracks;
extraction = MBS_SelectTrack;
m_tracks = true;
break;
case TRM:
query = MBQ_FindDistinctTRMId;
result = MBE_GetNumTrmids;
extraction = MBS_SelectTrack;
break;
case ArtistByID:
query = MBQ_GetArtistById;
result = MBE_GetNumArtists;
extraction = MBS_SelectArtist ;
break;
case AlbumByID:
query = MBQ_GetAlbumById;
result = MBE_GetNumAlbums;
extraction = MBS_SelectAlbum;
break;
case TrackByID:
query = MBQ_GetTrackById;
result = MBE_GetNumTracks;
extraction = MBS_SelectTrack;
m_tracks = true;
break;
default:
kdDebug(65432)<<"Unrecognized query reported"<<endl;
}
}
MusicBrainzQuery::Album MusicBrainzQuery::extractAlbum( int i )
{
std::string temp;
kdDebug()<<"Extracting "<<i<<endl;
Album alb;
GetIDFromURL( Data( MBE_AlbumGetAlbumId ), temp );
alb.id = temp.c_str();
alb.name = dataExtract( MBE_AlbumGetAlbumName );
alb.numTracks = DataInt( MBE_AlbumGetNumTracks );
alb.artist = dataExtract( MBE_AlbumGetArtistName, 1 );
GetIDFromURL( Data( MBE_AlbumGetArtistId, 1 ), temp );
alb.artistId = temp.c_str();
alb.status = dataExtract( MBE_AlbumGetAlbumStatus );
alb.type = dataExtract( MBE_AlbumGetAlbumType );
alb.cdIndexId = dataExtract( MBE_AlbumGetNumCdindexIds );
TrackList tracks;
for( int num = 1; num <= alb.numTracks; ++num ) {
tracks.append( extractTrackFromAlbum(num) );
}
alb.tracksList = tracks;
return alb;
}
MusicBrainzQuery::Track MusicBrainzQuery::extractTrackFromAlbum(int num)
{
Track track;
std::string temp;
track.num = num;
track.name = dataExtract(MBE_AlbumGetTrackName, num);
track.duration = dataExtract(MBE_AlbumGetTrackDuration, num);
track.artist = dataExtract(MBE_AlbumGetArtistName, num);
GetIDFromURL( Data(MBE_AlbumGetTrackId), temp );
track.id = ( temp.empty() )?QString::null: QString( temp.c_str() );
GetIDFromURL( Data(MBE_AlbumGetArtistId ), temp );
track.artistId = ( temp.empty() )? QString::null : QString( temp.c_str() );
return track;
}
MusicBrainzQuery::Track MusicBrainzQuery::extractTrack(int num)
{
Track track;
std::string temp1, temp2 = Data(MBE_TrackGetTrackId);
track.name = dataExtract(MBE_TrackGetTrackName, num);
track.duration = dataExtract(MBE_TrackGetTrackDuration, num);
track.artist = dataExtract(MBE_TrackGetArtistName, num);
track.album = dataExtract(MBE_AlbumGetAlbumName, num);
GetIDFromURL( temp2, temp1 );
track.id = ( temp1.empty() )?QString::null: QString( temp1.c_str() );
Select(MBS_SelectTrackAlbum);
track.num = GetOrdinalFromList(MBE_AlbumGetTrackList, temp2);
GetIDFromURL( Data(MBE_AlbumGetArtistId ), temp1 );
track.artistId = ( temp1.empty() )? QString::null : QString( temp1.c_str() );
Select(MBS_Rewind);
return track;
}
void MusicBrainzQuery::trmData(KProcess *, char *buffer, int buflen)
{
m_trm += QString::fromLatin1(buffer, buflen);
}
void MusicBrainzQuery::trmGenerationFinished(KProcess*)
{
m_arguments.clear();
m_arguments << m_trm;
m_query = TrackFromTRM;
kdDebug()<<"Generation finished "<<m_trm<<endl;
slotQuery();
}
#include "musicbrainzquery.moc"
#endif
// -*- Mode: c++-mode; c-basic-offset: 4; indent-tabs-mode: nil; -*-
// musicbrainzquery.h
//
// Copyright (C) 2003 Zack Rusin <zack@kde.org>
//
// This program 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 2
// of the License, or (at your option) any later version.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
#ifndef MUSICBRAINZ_H
#define MUSICBRAINZ_H
#include "../config.h"
#if HAVE_MUSICBRAINZ
#include <musicbrainz/musicbrainz.h>
#include <qobject.h>
#include <qstringlist.h>
class KProcess;
/**
* This is a class used to issue MusicBrainz queries.
* It's pseudo-asynchrnous. Pseudo because it depends on
* asynchrnous libmusicbrainz (someday we'll have to write
* our own KDE native one :) ). The type of queries are in the
* Query enum. You have to specify the query with arguments in
* the constructor. Connect to the query signals and issue the
* start() call on the job. So for example to find an album by
* name one would do :
*
* QStringList l;
* l<<"h2o";
* MusicBrainzQuery *query =
* new MusicBrainzQuery( MusicBrainzQuery::AlbumByName ,
* l );
* connect( query, SIGNAL(done(const MusicBrainzQuery::AlbumList&)),
* SLOT(slotDone(const MusicBrainzQuery::AlbumList&)) );
* query->start();
*
*/
class MusicBrainzQuery : public QObject,
public MusicBrainz
{
Q_OBJECT
public:
enum QueryType {
CD,//!identifies the cd , doesn't take any arguments
File,//!tries to identify the given file, takes file path
TrackFromTRM,//!identifies the song from trm, takes the trm
TrackFromID,//!song from track id, takes the trackId
ArtistByName,//!name
AlbumByName,//!name
TrackByName,//!name
TRM,//!artist name + track name
ArtistByID,//!artist id
AlbumByID,//!album id
TrackByID//!track id
};
struct Track {
int num;
QString id;
QString album;
QString name;
QString duration;
QString artist;
QString artistId;
};
typedef QValueList<Track> TrackList;
struct Album {
Album(): numTracks(0) {}
QString name;
QString artist;
QString id;
QString status;
QString type;
QString cdIndexId;
QString artistId;
int numTracks;
TrackList tracksList;
};
typedef QValueList<Album> AlbumList;
MusicBrainzQuery(QueryType query, QStringList args,
QObject* parent=0, const char* name=0);
void start();
signals:
void done(const MusicBrainzQuery::AlbumList&);
void done(const MusicBrainzQuery::TrackList&);
protected slots:
void slotQuery();
void trmData(KProcess *proc, char *buffer, int buflen);
void trmGenerationFinished(KProcess *proc);
protected:
void trmQuery(const QString& file);
QString dataExtract(const QString&, int i=0);
void queryStrings(std::string& query, std::string& result, std::string& extraction);
Album extractAlbum(int);
Track extractTrack(int);
Track extractTrackFromAlbum(int);
QueryType m_query;
QStringList m_arguments;
QString m_trm;
bool m_tracks;//if only tracks should be extracted
};
#endif
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment