1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-18 23:09:42 +01:00

Make Fuzzy Search usable

This commit is contained in:
Uwe L. Korn 2014-06-03 16:08:20 +01:00
parent b0c23a0740
commit 0b7449e488
5 changed files with 149 additions and 21 deletions

View File

@ -213,6 +213,12 @@ FuzzyIndex::deleteIndex()
TomahawkUtils::removeDirectory( m_lucenePath );
}
void
FuzzyIndex::updateIndex()
{
// NO-OP
}
void
FuzzyIndex::loadLuceneIndex()

View File

@ -68,20 +68,20 @@ public:
*/
void deleteIndex();
virtual void updateIndex() = 0;
virtual void updateIndex();
signals:
void indexReady();
public slots:
void loadLuceneIndex();
bool wipeIndex();
QMap< int, float > search( const Tomahawk::query_ptr& query );
QMap< int, float > searchAlbum( const Tomahawk::query_ptr& query );
private slots:
void updateIndexSlot();
bool wipeIndex();
private:
QMutex m_mutex;

View File

@ -188,6 +188,13 @@ JSResolver::init()
{
Q_D( JSResolver );
QString lucenePath = d->accountId + ".lucene";
QDir luceneDir( TomahawkUtils::appDataDir().absoluteFilePath( lucenePath ) );
if ( luceneDir.exists() )
{
d->fuzzyIndex.reset( new FuzzyIndex( this, lucenePath, false ) );
}
QFile scriptFile( filePath() );
if( !scriptFile.open( QIODevice::ReadOnly ) )
{

View File

@ -494,49 +494,158 @@ JSResolverHelper::hasFuzzyIndex()
}
bool
JSResolverHelper::indexDataFromVariant( const QVariantMap &map, struct Tomahawk::IndexData& indexData )
{
// We do not use artistId at the moment
indexData.artistId = 0;
if ( map.contains( "album" ) )
{
indexData.album = map["album"].toString();
}
else
{
indexData.album = QString();
}
// Check that we have the three required attributes
if ( !map.contains( "id" ) || !map["id"].canConvert( QVariant::Int )
|| !map.contains( "track" ) || !map.contains( "artist" ) )
{
return false;
}
bool ok;
indexData.id = map["id"].toInt( &ok );
if ( !ok )
{
return false;
}
indexData.artist = map["artist"].toString().trimmed();
if ( indexData.artist.isEmpty() )
{
return false;
}
indexData.track = map["track"].toString().trimmed();
if ( indexData.track.isEmpty() )
{
return false;
}
return true;
}
void
JSResolverHelper::createFuzzyIndex( const QVariantList& list )
{
// TODO
if ( m_resolver->d_func()->fuzzyIndex.isNull() )
{
m_resolver->d_func()->fuzzyIndex.reset( new FuzzyIndex( m_resolver, m_resolver->d_func()->accountId + ".lucene" , true ) );
}
else
{
m_resolver->d_func()->fuzzyIndex->wipeIndex();
}
addToFuzzyIndex( list );
}
void
JSResolverHelper::addToFuzzyIndex( const QVariantList& list )
{
// TODO
if ( m_resolver->d_func()->fuzzyIndex.isNull() )
{
tLog() << Q_FUNC_INFO << "Cannot add entries to non-existing index.";
return;
}
m_resolver->d_func()->fuzzyIndex->beginIndexing();
foreach ( const QVariant& variant, list )
{
// Convert each entry to IndexData
if ( variant.canConvert( QVariant::Map ) ) {
QVariantMap map = variant.toMap();
// Convert each entry and do multiple checks that we have valid data.
struct IndexData indexData;
if ( indexDataFromVariant( map, indexData ) )
{
m_resolver->d_func()->fuzzyIndex->appendFields( indexData );
}
}
}
m_resolver->d_func()->fuzzyIndex->endIndexing();
}
QMap<int, float>
bool
cmpTuple ( QVariant x, QVariant y )
{
return x.toList().at( 1 ).toFloat() < y.toList().at( 1 ).toFloat();
}
QVariantList
JSResolverHelper::searchInFuzzyIndex( const query_ptr& query )
{
if ( m_resolver->d_func()->fuzzyIndex )
{
QMap<int, float> map = m_resolver->d_func()->fuzzyIndex->search( query );
// Convert map to sorted QVariantList
QVariantList list;
foreach ( int id, map.keys() ) {
QVariantList innerList;
innerList.append( QVariant( id ) );
innerList.append( QVariant( map[id] ) );
// Wrap into QVariant or the list will be flattend
list.append( QVariant( innerList ));
}
std::sort( list.begin(), list.end(), cmpTuple );
return list;
}
return QVariantList();
}
QVariantList
JSResolverHelper::searchFuzzyIndex( const QString& query )
{
if ( m_resolver->d_func()->fuzzyIndex )
{
return m_resolver->d_func()->fuzzyIndex->search( Query::get( query, QString() ) );
}
return QMap<int, float>();
return searchInFuzzyIndex( Query::get( query, QString() ) );
}
QMap<int, float>
QVariantList
JSResolverHelper::resolveFromFuzzyIndex( const QString& artist, const QString& album, const QString& track )
{
if ( m_resolver->d_func()->fuzzyIndex )
{
// Important: Do not autoresolve!
query_ptr query = Query::get( artist, album, track, QString(), false );
return m_resolver->d_func()->fuzzyIndex->search( query );
// Important: Do not autoresolve!
query_ptr query = Query::get( artist, track, album, QString(), false );
if ( query.isNull() ) {
tLog() << Q_FUNC_INFO << "Could not create a query for" << artist << "-" << track;
return QVariantList();
}
return QMap<int, float>();
return searchInFuzzyIndex( query );
}
void
JSResolverHelper::deleteFuzzyIndex()
{
m_resolver->d_func()->fuzzyIndex->deleteIndex();
m_resolver->d_func()->fuzzyIndex->deleteLater();
if ( m_resolver->d_func()->fuzzyIndex )
{
m_resolver->d_func()->fuzzyIndex->deleteIndex();
m_resolver->d_func()->fuzzyIndex->deleteLater();
m_resolver->d_func()->fuzzyIndex.reset();
}
}
@ -564,6 +673,7 @@ JSResolverHelper::returnStreamUrl( const QString& streamUrl, const QMap<QString,
}
}
Q_DECLARE_METATYPE( IODeviceCallback )
void

View File

@ -25,6 +25,7 @@
#include "DllMacro.h"
#include "Typedefs.h"
#include "UrlHandler.h"
#include "database/fuzzyindex/FuzzyIndex.h"
#include "utils/NetworkReply.h"
#include <boost/function.hpp>
@ -32,6 +33,7 @@
#include <QObject>
#include <QVariantMap>
class JSResolver;
Q_DECLARE_METATYPE( boost::function< void( QSharedPointer< QIODevice >& ) > )
@ -54,8 +56,8 @@ public:
Q_INVOKABLE bool hasFuzzyIndex();
Q_INVOKABLE void createFuzzyIndex( const QVariantList& list );
Q_INVOKABLE void addToFuzzyIndex( const QVariantList& list );
Q_INVOKABLE QMap<int, float> searchFuzzyIndex( const QString& query );
Q_INVOKABLE QMap<int, float> resolveFromFuzzyIndex( const QString& artist, const QString& album, const QString& tracks );
Q_INVOKABLE QVariantList searchFuzzyIndex( const QString& query );
Q_INVOKABLE QVariantList resolveFromFuzzyIndex( const QString& artist, const QString& album, const QString& tracks );
Q_INVOKABLE void deleteFuzzyIndex();
void customIODeviceFactory( const Tomahawk::result_ptr&, const QString& url,
@ -93,6 +95,9 @@ private:
void returnStreamUrl( const QString& streamUrl, const QMap<QString, QString>& headers,
boost::function< void( const QString&, QSharedPointer< QIODevice >& ) > callback );
bool indexDataFromVariant( const QVariantMap& map, struct Tomahawk::IndexData& indexData );
QVariantList searchInFuzzyIndex( const Tomahawk::query_ptr& query );
QVariantMap m_resolverConfig;
JSResolver* m_resolver;
QString m_scriptPath, m_urlCallback, m_urlTranslator;