mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-08-20 21:02:26 +02:00
Merge branch 'master' of github.com:tomahawk-player/tomahawk
Conflicts: src/libtomahawk/tomahawksettings.cpp src/libtomahawk/tomahawksettings.h src/sip/jreen/jabber.cpp src/sip/jreen/jabber.h src/tomahawkapp.cpp src/tomahawkwindow.h thirdparty/jreen
This commit is contained in:
@@ -39,6 +39,11 @@ INCLUDE( MacroLogFeature )
|
|||||||
set(LIBLASTFM_FOUND true)
|
set(LIBLASTFM_FOUND true)
|
||||||
|
|
||||||
find_package(Phonon REQUIRED)
|
find_package(Phonon REQUIRED)
|
||||||
|
if(PHONON_VERSION STRLESS "4.5.0")
|
||||||
|
message(FATAL_ERROR "Phonon version 4.5.0 or higher is required, you have version ${PHONON_VERSION}")
|
||||||
|
else()
|
||||||
|
message(STATUS "Phonon found; ensure that phonon-vlc is at least 0.4")
|
||||||
|
endif()
|
||||||
|
|
||||||
macro_optional_find_package(LibEchonest 1.1.1)
|
macro_optional_find_package(LibEchonest 1.1.1)
|
||||||
macro_log_feature(LIBECHONEST_FOUND "Echonest" "Qt library for communicating with The Echo Nest" "http://projects.kde.org/libechonest" TRUE "" "libechonest is needed for dynamic playlists and the infosystem")
|
macro_log_feature(LIBECHONEST_FOUND "Echonest" "Qt library for communicating with The Echo Nest" "http://projects.kde.org/libechonest" TRUE "" "libechonest is needed for dynamic playlists and the infosystem")
|
||||||
|
@@ -31,11 +31,11 @@ else(PHONON_FOUND)
|
|||||||
endif(PHONON_INCLUDE_DIR AND PHONON_LIBRARY)
|
endif(PHONON_INCLUDE_DIR AND PHONON_LIBRARY)
|
||||||
|
|
||||||
# As discussed on kde-buildsystem: first look at CMAKE_PREFIX_PATH, then at the suggested PATHS (kde4 install dir)
|
# As discussed on kde-buildsystem: first look at CMAKE_PREFIX_PATH, then at the suggested PATHS (kde4 install dir)
|
||||||
find_library(PHONON_LIBRARY NAMES phonon phonon4 PATHS ${KDE4_LIB_INSTALL_DIR} ${QT_LIBRARY_DIR} NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH)
|
find_library(PHONON_LIBRARY NAMES phonon phonon4 PATHS ${KDE4_LIB_INSTALL_DIR} ${QT_LIBRARY_DIR})
|
||||||
# then at the default system locations (CMAKE_SYSTEM_PREFIX_PATH, i.e. /usr etc.)
|
# then at the default system locations (CMAKE_SYSTEM_PREFIX_PATH, i.e. /usr etc.)
|
||||||
find_library(PHONON_LIBRARY NAMES phonon phonon4)
|
find_library(PHONON_LIBRARY NAMES phonon phonon4)
|
||||||
|
|
||||||
find_path(PHONON_INCLUDE_DIR NAMES phonon/phonon_export.h PATHS ${KDE4_INCLUDE_INSTALL_DIR} ${QT_INCLUDE_DIR} ${INCLUDE_INSTALL_DIR} ${QT_LIBRARY_DIR} NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH)
|
find_path(PHONON_INCLUDE_DIR NAMES phonon/phonon_export.h PATHS ${KDE4_INCLUDE_INSTALL_DIR} ${QT_INCLUDE_DIR} ${INCLUDE_INSTALL_DIR} ${QT_LIBRARY_DIR})
|
||||||
find_path(PHONON_INCLUDE_DIR NAMES phonon/phonon_export.h)
|
find_path(PHONON_INCLUDE_DIR NAMES phonon/phonon_export.h)
|
||||||
|
|
||||||
if(PHONON_INCLUDE_DIR AND PHONON_LIBRARY)
|
if(PHONON_INCLUDE_DIR AND PHONON_LIBRARY)
|
||||||
|
@@ -39,6 +39,7 @@ SET( tomahawkSources ${tomahawkSources}
|
|||||||
|
|
||||||
musicscanner.cpp
|
musicscanner.cpp
|
||||||
shortcuthandler.cpp
|
shortcuthandler.cpp
|
||||||
|
globalactionmanager.cpp
|
||||||
scanmanager.cpp
|
scanmanager.cpp
|
||||||
tomahawkapp.cpp
|
tomahawkapp.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
@@ -83,6 +84,7 @@ SET( tomahawkHeaders ${tomahawkHeaders}
|
|||||||
musicscanner.h
|
musicscanner.h
|
||||||
scanmanager.h
|
scanmanager.h
|
||||||
shortcuthandler.h
|
shortcuthandler.h
|
||||||
|
globalactionmanager.h
|
||||||
)
|
)
|
||||||
|
|
||||||
IF(LIBLASTFM_FOUND)
|
IF(LIBLASTFM_FOUND)
|
||||||
|
360
src/globalactionmanager.cpp
Normal file
360
src/globalactionmanager.cpp
Normal file
@@ -0,0 +1,360 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2011 Leo Franchi <lfranchi@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.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "globalactionmanager.h"
|
||||||
|
|
||||||
|
#include "audio/audioengine.h"
|
||||||
|
#include "utils/xspfloader.h"
|
||||||
|
#include "sourcelist.h"
|
||||||
|
#include "playlist/dynamic/GeneratorInterface.h"
|
||||||
|
#include "viewmanager.h"
|
||||||
|
#include "playlist/topbar/topbar.h"
|
||||||
|
#include "pipeline.h"
|
||||||
|
#include "database/localcollection.h"
|
||||||
|
#include "playlist/playlistview.h"
|
||||||
|
#include "echonest/Playlist.h"
|
||||||
|
|
||||||
|
#include <QUrl>
|
||||||
|
#include <Playlist.h>
|
||||||
|
|
||||||
|
GlobalActionManager* GlobalActionManager::s_instance = 0;
|
||||||
|
|
||||||
|
GlobalActionManager*
|
||||||
|
GlobalActionManager::instance()
|
||||||
|
{
|
||||||
|
if( !s_instance )
|
||||||
|
s_instance = new GlobalActionManager;
|
||||||
|
|
||||||
|
return s_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GlobalActionManager::GlobalActionManager( QObject* parent )
|
||||||
|
: QObject( parent )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GlobalActionManager::~GlobalActionManager()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GlobalActionManager::parseTomahawkLink( const QString& url )
|
||||||
|
{
|
||||||
|
if( url.contains( "tomahawk://" ) ) {
|
||||||
|
QString cmd = url.mid( 11 );
|
||||||
|
qDebug() << "Parsing tomahawk link command" << cmd;
|
||||||
|
|
||||||
|
QString cmdType = cmd.split( "/" ).first();
|
||||||
|
QUrl u( cmd );
|
||||||
|
|
||||||
|
// for backwards compatibility
|
||||||
|
if( cmdType == "load" ) {
|
||||||
|
if( u.hasQueryItem( "xspf" ) ) {
|
||||||
|
QUrl xspf = QUrl::fromUserInput( u.queryItemValue( "xspf" ) );
|
||||||
|
XSPFLoader* l = new XSPFLoader( true, this );
|
||||||
|
qDebug() << "Loading spiff:" << xspf.toString();
|
||||||
|
l->load( xspf );
|
||||||
|
connect( l, SIGNAL( ok( Tomahawk::playlist_ptr ) ), ViewManager::instance(), SLOT( show( Tomahawk::playlist_ptr ) ) );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( cmdType == "playlist" ) {
|
||||||
|
return handlePlaylistCommand( u );
|
||||||
|
} else if( cmdType == "collection" ) {
|
||||||
|
return handleCollectionCommand( u );
|
||||||
|
} else if( cmdType == "queue" ) {
|
||||||
|
return handleQueueCommand( u );
|
||||||
|
} else if( cmdType == "station" ) {
|
||||||
|
return handleStationCommand( u );
|
||||||
|
} else if( cmdType == "search" ) {
|
||||||
|
return handleSearchCommand( u );
|
||||||
|
} else if( cmdType == "play" ) {
|
||||||
|
return handlePlayCommand( u );
|
||||||
|
} else {
|
||||||
|
qDebug() << "Tomahawk link not supported, command not known!" << cmdType << u.path();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qDebug() << "Not a tomahawk:// link!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GlobalActionManager::handlePlaylistCommand( const QUrl& url )
|
||||||
|
{
|
||||||
|
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
||||||
|
if( parts.isEmpty() ) {
|
||||||
|
qDebug() << "No specific playlist command:" << url.toString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( parts[ 0 ] == "import" ) {
|
||||||
|
if( !url.hasQueryItem( "xspf" ) ) {
|
||||||
|
qDebug() << "No xspf to load..";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QUrl xspf = QUrl( url.queryItemValue( "xspf" ) );
|
||||||
|
QString title = url.hasQueryItem( "title" ) ? url.queryItemValue( "title" ) : QString();
|
||||||
|
XSPFLoader* l= new XSPFLoader( true, this );
|
||||||
|
l->setOverrideTitle( title );
|
||||||
|
l->load( xspf );
|
||||||
|
connect( l, SIGNAL( ok( Tomahawk::playlist_ptr ) ), ViewManager::instance(), SLOT( show( Tomahawk::playlist_ptr ) ) );
|
||||||
|
|
||||||
|
} else if( parts [ 0 ] == "new" ) {
|
||||||
|
if( !url.hasQueryItem( "title" ) ) {
|
||||||
|
qDebug() << "New playlist command needs a title...";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Tomahawk::playlist_ptr pl = Tomahawk::Playlist::create( SourceList::instance()->getLocal(), uuid(), url.queryItemValue( "title" ), QString(), QString(), false );
|
||||||
|
pl->createNewRevision( uuid(), pl->currentrevision(), QList< Tomahawk::plentry_ptr >() );
|
||||||
|
ViewManager::instance()->show( pl );
|
||||||
|
} else if( parts[ 0 ] == "add" ) {
|
||||||
|
if( !url.hasQueryItem( "playlistid" ) || !url.hasQueryItem( "track" ) || !url.hasQueryItem( "artist" ) ) {
|
||||||
|
qDebug() << "Add to playlist command needs playlistid, track, and artist..." << url.toString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// TODO implement. Let the user select what playlist to add to
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GlobalActionManager::handleCollectionCommand( const QUrl& url )
|
||||||
|
{
|
||||||
|
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
||||||
|
if( parts.isEmpty() ) {
|
||||||
|
qDebug() << "No specific collection command:" << url.toString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( parts[ 0 ] == "add" ) {
|
||||||
|
// TODO implement
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GlobalActionManager::handleQueueCommand( const QUrl& url )
|
||||||
|
{
|
||||||
|
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
||||||
|
if( parts.isEmpty() ) {
|
||||||
|
qDebug() << "No specific queue command:" << url.toString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( parts[ 0 ] == "add" ) {
|
||||||
|
if( parts.size() > 1 && parts[ 1 ] == "track" ) {
|
||||||
|
QPair< QString, QString > pair;
|
||||||
|
foreach( pair, url.queryItems() ) {
|
||||||
|
if( pair.first != "url" )
|
||||||
|
continue;
|
||||||
|
QUrl track = QUrl::fromUserInput( pair.second );
|
||||||
|
//FIXME: isLocalFile is Qt 4.8
|
||||||
|
if( track.toString().startsWith( "file://" ) ) { // it's local, so we see if it's in the DB and load it if so
|
||||||
|
// TODO
|
||||||
|
} else { // give it a web result hint
|
||||||
|
// TODO actually read the tags
|
||||||
|
QFileInfo info( track.path() );
|
||||||
|
Tomahawk::query_ptr q = Tomahawk::Query::get( QString(), info.baseName(), QString() );
|
||||||
|
q->setResultHint( track.toString() );
|
||||||
|
Tomahawk::Pipeline::instance()->resolve( q, true );
|
||||||
|
|
||||||
|
ViewManager::instance()->queue()->model()->append( q );
|
||||||
|
ViewManager::instance()->showQueue();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
qDebug() << "Only queue/add/track is support at the moment, got:" << parts;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GlobalActionManager::handleSearchCommand( const QUrl& url )
|
||||||
|
{
|
||||||
|
// open the super collection and set this as the search filter
|
||||||
|
QStringList query;
|
||||||
|
if( url.hasQueryItem( "artist" ) )
|
||||||
|
query << url.queryItemValue( "artist" );
|
||||||
|
if( url.hasQueryItem( "album" ) )
|
||||||
|
query << url.queryItemValue( "album" );
|
||||||
|
if( url.hasQueryItem( "track" ) )
|
||||||
|
query << url.queryItemValue( "track" );
|
||||||
|
QString queryStr = query.join( " " );
|
||||||
|
|
||||||
|
if( queryStr.isEmpty() )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ViewManager::instance()->showSuperCollection();
|
||||||
|
ViewManager::instance()->topbar()->setFilter( queryStr );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GlobalActionManager::handleStationCommand( const QUrl& url )
|
||||||
|
{
|
||||||
|
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
||||||
|
if( parts.isEmpty() ) {
|
||||||
|
qDebug() << "No specific station command:" << url.toString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( parts[ 0 ] == "create" ) {
|
||||||
|
if( !url.hasQueryItem( "title" ) || !url.hasQueryItem( "type" ) ) {
|
||||||
|
qDebug() << "Station create command needs title and type..." << url.toString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QString title = url.queryItemValue( "title" );
|
||||||
|
QString type = url.queryItemValue( "type" );
|
||||||
|
Tomahawk::dynplaylist_ptr pl = Tomahawk::DynamicPlaylist::create( SourceList::instance()->getLocal(), uuid(), title, QString(), QString(), Tomahawk::OnDemand, false, type );
|
||||||
|
QList< Tomahawk::dyncontrol_ptr > controls;
|
||||||
|
QPair< QString, QString > param;
|
||||||
|
foreach( param, url.queryItems() ) {
|
||||||
|
if( param.first == "artist" ) {
|
||||||
|
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Artist" );
|
||||||
|
c->setInput( param.second );
|
||||||
|
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistRadioType ) );
|
||||||
|
controls << c;
|
||||||
|
} /*else if( param.first == "hotttnesss" ) { TODO
|
||||||
|
Tomahawk::dyncontrol_ptr c = pl->generator()->createControl( "Artist" );
|
||||||
|
c->setInput( param.second );
|
||||||
|
c->setMatch( 0 );
|
||||||
|
controls << c;
|
||||||
|
} */
|
||||||
|
}
|
||||||
|
pl->createNewRevision( uuid(), pl->currentrevision(), type, controls );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
GlobalActionManager::handlePlayCommand( const QUrl& url )
|
||||||
|
{
|
||||||
|
QStringList parts = url.path().split( "/" ).mid( 1 ); // get the rest of the command
|
||||||
|
if( parts.isEmpty() ) {
|
||||||
|
qDebug() << "No specific play command:" << url.toString();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( parts[ 0 ] == "track" ) {
|
||||||
|
QPair< QString, QString > pair;
|
||||||
|
QString title, artist, album, urlStr;
|
||||||
|
foreach( pair, url.queryItems() ) {
|
||||||
|
if( pair.first == "track" )
|
||||||
|
title = pair.second;
|
||||||
|
else if( pair.first == "artist" )
|
||||||
|
artist = pair.second;
|
||||||
|
else if( pair.first == "album" )
|
||||||
|
album = pair.second;
|
||||||
|
else if( pair.first == "url" )
|
||||||
|
urlStr = pair.second;
|
||||||
|
}
|
||||||
|
Tomahawk::query_ptr q = Tomahawk::Query::get( artist, title, album );
|
||||||
|
if( !urlStr.isEmpty() )
|
||||||
|
q->setResultHint( urlStr );
|
||||||
|
Tomahawk::Pipeline::instance()->resolve( q, true );
|
||||||
|
|
||||||
|
// now we add it to the special "bookmarks" playlist, creating it if it doesn't exist. if nothing is playing, start playing the track
|
||||||
|
QSharedPointer< LocalCollection > col = SourceList::instance()->getLocal()->collection().dynamicCast< LocalCollection >();
|
||||||
|
Tomahawk::playlist_ptr bookmarkpl = col->bookmarksPlaylist();
|
||||||
|
if( bookmarkpl.isNull() ) { // create it and do the deed then
|
||||||
|
m_waitingToBookmark = q;
|
||||||
|
col->createBookmarksPlaylist();
|
||||||
|
connect( col.data(), SIGNAL( bookmarkPlaylistCreated( Tomahawk::playlist_ptr ) ), this, SLOT( bookmarkPlaylistCreated( Tomahawk::playlist_ptr ) ), Qt::UniqueConnection );
|
||||||
|
} else {
|
||||||
|
doBookmark( bookmarkpl, q );
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GlobalActionManager::bookmarkPlaylistCreated( const Tomahawk::playlist_ptr& pl )
|
||||||
|
{
|
||||||
|
Q_ASSERT( !m_waitingToBookmark.isNull() );
|
||||||
|
doBookmark( pl, m_waitingToBookmark );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GlobalActionManager::doBookmark( const Tomahawk::playlist_ptr& pl, const Tomahawk::query_ptr& q )
|
||||||
|
{
|
||||||
|
Tomahawk::plentry_ptr e( new Tomahawk::PlaylistEntry );
|
||||||
|
e->setGuid( uuid() );
|
||||||
|
|
||||||
|
if ( q->results().count() )
|
||||||
|
e->setDuration( q->results().at( 0 )->duration() );
|
||||||
|
else
|
||||||
|
e->setDuration( 0 );
|
||||||
|
|
||||||
|
e->setLastmodified( 0 );
|
||||||
|
e->setAnnotation( "" ); // FIXME
|
||||||
|
e->setQuery( q );
|
||||||
|
|
||||||
|
pl->createNewRevision( uuid(), pl->currentrevision(), QList< Tomahawk::plentry_ptr >( pl->entries() ) << e );
|
||||||
|
connect( pl.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( showPlaylist() ) );
|
||||||
|
|
||||||
|
m_toShow = pl;
|
||||||
|
|
||||||
|
// if nothing is playing, lets start this
|
||||||
|
// TODO
|
||||||
|
if( !AudioEngine::instance()->isPlaying() ) {
|
||||||
|
connect( q.data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( waitingForResolved( bool ) ) );
|
||||||
|
m_waitingToPlay = q;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_waitingToBookmark.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GlobalActionManager::showPlaylist()
|
||||||
|
{
|
||||||
|
if( m_toShow.isNull() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
ViewManager::instance()->show( m_toShow );
|
||||||
|
|
||||||
|
m_toShow.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GlobalActionManager::waitingForResolved( bool success )
|
||||||
|
{
|
||||||
|
if( success && !m_waitingToPlay.isNull() && !m_waitingToPlay->results().isEmpty() ) { // play it!
|
||||||
|
AudioEngine::instance()->playItem( AudioEngine::instance()->playlist(), m_waitingToPlay->results().first() );
|
||||||
|
}
|
||||||
|
|
||||||
|
m_waitingToPlay.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
61
src/globalactionmanager.h
Normal file
61
src/globalactionmanager.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2011 Leo Franchi <lfranchi@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.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef GLOBALACTIONMANAGER_H
|
||||||
|
#define GLOBALACTIONMANAGER_H
|
||||||
|
|
||||||
|
#include "playlist.h"
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
class GlobalActionManager : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
static GlobalActionManager* instance();
|
||||||
|
virtual ~GlobalActionManager();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
bool parseTomahawkLink( const QString& link );
|
||||||
|
void waitingForResolved( bool );
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void bookmarkPlaylistCreated( const Tomahawk::playlist_ptr& pl );
|
||||||
|
void showPlaylist();
|
||||||
|
|
||||||
|
private:
|
||||||
|
explicit GlobalActionManager( QObject* parent = 0 );
|
||||||
|
void doBookmark( const Tomahawk::playlist_ptr& pl, const Tomahawk::query_ptr& q );
|
||||||
|
|
||||||
|
bool handlePlaylistCommand( const QUrl& url );
|
||||||
|
bool handleCollectionCommand(const QUrl& url );
|
||||||
|
bool handleQueueCommand(const QUrl& url );
|
||||||
|
bool handleStationCommand(const QUrl& url );
|
||||||
|
bool handleSearchCommand(const QUrl& url );
|
||||||
|
bool handlePlayCommand(const QUrl& url );
|
||||||
|
|
||||||
|
Tomahawk::playlist_ptr m_toShow;
|
||||||
|
Tomahawk::query_ptr m_waitingToBookmark;
|
||||||
|
Tomahawk::query_ptr m_waitingToPlay;
|
||||||
|
|
||||||
|
static GlobalActionManager* s_instance;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // GLOBALACTIONMANAGER_H
|
@@ -21,6 +21,7 @@ set( libSources
|
|||||||
artist.cpp
|
artist.cpp
|
||||||
album.cpp
|
album.cpp
|
||||||
collection.cpp
|
collection.cpp
|
||||||
|
webcollection.cpp
|
||||||
playlist.cpp
|
playlist.cpp
|
||||||
resolver.cpp
|
resolver.cpp
|
||||||
query.cpp
|
query.cpp
|
||||||
@@ -38,6 +39,7 @@ set( libSources
|
|||||||
database/database.cpp
|
database/database.cpp
|
||||||
database/fuzzyindex.cpp
|
database/fuzzyindex.cpp
|
||||||
database/databasecollection.cpp
|
database/databasecollection.cpp
|
||||||
|
database/localcollection.cpp
|
||||||
database/databaseworker.cpp
|
database/databaseworker.cpp
|
||||||
database/databaseimpl.cpp
|
database/databaseimpl.cpp
|
||||||
database/databaseresolver.cpp
|
database/databaseresolver.cpp
|
||||||
@@ -66,7 +68,6 @@ set( libSources
|
|||||||
database/databasecommand_renameplaylist.cpp
|
database/databasecommand_renameplaylist.cpp
|
||||||
database/databasecommand_loadops.cpp
|
database/databasecommand_loadops.cpp
|
||||||
database/databasecommand_updatesearchindex.cpp
|
database/databasecommand_updatesearchindex.cpp
|
||||||
database/databasecollection.cpp
|
|
||||||
database/databasecommand_setdynamicplaylistrevision.cpp
|
database/databasecommand_setdynamicplaylistrevision.cpp
|
||||||
database/databasecommand_createdynamicplaylist.cpp
|
database/databasecommand_createdynamicplaylist.cpp
|
||||||
database/databasecommand_loaddynamicplaylist.cpp
|
database/databasecommand_loaddynamicplaylist.cpp
|
||||||
@@ -79,6 +80,7 @@ set( libSources
|
|||||||
|
|
||||||
infosystem/infosystemcache.cpp
|
infosystem/infosystemcache.cpp
|
||||||
infosystem/infosystem.cpp
|
infosystem/infosystem.cpp
|
||||||
|
infosystem/infosystemworker.cpp
|
||||||
infosystem/infoplugins/echonestplugin.cpp
|
infosystem/infoplugins/echonestplugin.cpp
|
||||||
infosystem/infoplugins/lastfmplugin.cpp
|
infosystem/infoplugins/lastfmplugin.cpp
|
||||||
infosystem/infoplugins/musixmatchplugin.cpp
|
infosystem/infoplugins/musixmatchplugin.cpp
|
||||||
@@ -174,6 +176,7 @@ set( libHeaders
|
|||||||
|
|
||||||
aclsystem.h
|
aclsystem.h
|
||||||
collection.h
|
collection.h
|
||||||
|
webcollection.h
|
||||||
query.h
|
query.h
|
||||||
resolver.h
|
resolver.h
|
||||||
result.h
|
result.h
|
||||||
@@ -223,6 +226,7 @@ set( libHeaders
|
|||||||
database/databasecommand_loadops.h
|
database/databasecommand_loadops.h
|
||||||
database/databasecommand_updatesearchindex.h
|
database/databasecommand_updatesearchindex.h
|
||||||
database/databasecollection.h
|
database/databasecollection.h
|
||||||
|
database/localcollection.h
|
||||||
database/databasecommand_setdynamicplaylistrevision.h
|
database/databasecommand_setdynamicplaylistrevision.h
|
||||||
database/databasecommand_createdynamicplaylist.h
|
database/databasecommand_createdynamicplaylist.h
|
||||||
database/databasecommand_loaddynamicplaylist.h
|
database/databasecommand_loaddynamicplaylist.h
|
||||||
@@ -233,6 +237,7 @@ set( libHeaders
|
|||||||
database/databasecommand_clientauthvalid.h
|
database/databasecommand_clientauthvalid.h
|
||||||
|
|
||||||
infosystem/infosystem.h
|
infosystem/infosystem.h
|
||||||
|
infosystem/infosystemworker.h
|
||||||
infosystem/infosystemcache.h
|
infosystem/infosystemcache.h
|
||||||
infosystem/infoplugins/echonestplugin.h
|
infosystem/infoplugins/echonestplugin.h
|
||||||
infosystem/infoplugins/lastfmplugin.h
|
infosystem/infoplugins/lastfmplugin.h
|
||||||
|
@@ -113,12 +113,6 @@ AudioEngine::stop()
|
|||||||
m_expectStop = true;
|
m_expectStop = true;
|
||||||
m_mediaObject->stop();
|
m_mediaObject->stop();
|
||||||
|
|
||||||
if ( !m_input.isNull() )
|
|
||||||
{
|
|
||||||
m_input->close();
|
|
||||||
m_input.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
setCurrentTrack( Tomahawk::result_ptr() );
|
setCurrentTrack( Tomahawk::result_ptr() );
|
||||||
emit stopped();
|
emit stopped();
|
||||||
}
|
}
|
||||||
@@ -198,8 +192,6 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
|||||||
m_expectStop = true;
|
m_expectStop = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_input = io;
|
|
||||||
|
|
||||||
if ( !m_currentTrack->url().startsWith( "http://" ) )
|
if ( !m_currentTrack->url().startsWith( "http://" ) )
|
||||||
{
|
{
|
||||||
m_mediaObject->setCurrentSource( io.data() );
|
m_mediaObject->setCurrentSource( io.data() );
|
||||||
@@ -215,6 +207,9 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
|||||||
}
|
}
|
||||||
m_mediaObject->setCurrentSource( furl );
|
m_mediaObject->setCurrentSource( furl );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_input = io;
|
||||||
|
|
||||||
m_mediaObject->currentSource().setAutoDelete( true );
|
m_mediaObject->currentSource().setAutoDelete( true );
|
||||||
m_mediaObject->play();
|
m_mediaObject->play();
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
@@ -41,7 +41,7 @@ DatabaseCommand_Resolve::exec( DatabaseImpl* lib )
|
|||||||
{
|
{
|
||||||
qDebug() << "Using result-hint to speed up resolving:" << m_query->resultHint();
|
qDebug() << "Using result-hint to speed up resolving:" << m_query->resultHint();
|
||||||
|
|
||||||
Tomahawk::result_ptr result = lib->result( m_query->resultHint() );
|
Tomahawk::result_ptr result = lib->resultFromHint( m_query );
|
||||||
if ( !result.isNull() && result->collection()->source()->isOnline() )
|
if ( !result.isNull() && result->collection()->source()->isOnline() )
|
||||||
{
|
{
|
||||||
res << result;
|
res << result;
|
||||||
@@ -119,7 +119,7 @@ DatabaseCommand_Resolve::exec( DatabaseImpl* lib )
|
|||||||
s = SourceList::instance()->get( files_query.value( 13 ).toUInt() );
|
s = SourceList::instance()->get( files_query.value( 13 ).toUInt() );
|
||||||
if( s.isNull() )
|
if( s.isNull() )
|
||||||
{
|
{
|
||||||
Q_ASSERT( false );
|
qDebug() << "WTF: Could not find source" << files_query.value( 13 ).toUInt();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
@@ -60,7 +60,7 @@ DatabaseCommand_SetPlaylistRevision::postCommitHook()
|
|||||||
qDebug() << "Source has gone offline, not emitting to GUI.";
|
qDebug() << "Source has gone offline, not emitting to GUI.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( m_localOnly )
|
if ( m_localOnly )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -149,6 +149,8 @@ DatabaseCommand_SetPlaylistRevision::exec( DatabaseImpl* lib )
|
|||||||
QString resultHint;
|
QString resultHint;
|
||||||
if ( !e->query()->results().isEmpty() )
|
if ( !e->query()->results().isEmpty() )
|
||||||
resultHint = e->query()->results().first()->url();
|
resultHint = e->query()->results().first()->url();
|
||||||
|
else if ( !e->query()->resultHint().isEmpty() )
|
||||||
|
resultHint = e->query()->resultHint();
|
||||||
|
|
||||||
adde.bindValue( 0, e->guid() );
|
adde.bindValue( 0, e->guid() );
|
||||||
adde.bindValue( 1, m_playlistguid );
|
adde.bindValue( 1, m_playlistguid );
|
||||||
|
@@ -528,8 +528,9 @@ DatabaseImpl::album( int id )
|
|||||||
|
|
||||||
|
|
||||||
Tomahawk::result_ptr
|
Tomahawk::result_ptr
|
||||||
DatabaseImpl::result( const QString& url )
|
DatabaseImpl::resultFromHint( const Tomahawk::query_ptr& origquery )
|
||||||
{
|
{
|
||||||
|
QString url = origquery->resultHint();
|
||||||
TomahawkSqlQuery query = newquery();
|
TomahawkSqlQuery query = newquery();
|
||||||
Tomahawk::source_ptr s;
|
Tomahawk::source_ptr s;
|
||||||
Tomahawk::result_ptr res;
|
Tomahawk::result_ptr res;
|
||||||
@@ -552,7 +553,18 @@ DatabaseImpl::result( const QString& url )
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Q_ASSERT( false );
|
// Q_ASSERT( false );
|
||||||
qDebug() << "We don't support non-servent / non-file result-hints yet.";
|
// qDebug() << "We don't support non-servent / non-file result-hints yet.";
|
||||||
|
res = Tomahawk::result_ptr( new Tomahawk::Result() );
|
||||||
|
s = SourceList::instance()->webSource();
|
||||||
|
res->setUrl( url );
|
||||||
|
res->setCollection( s->collection() );
|
||||||
|
res->setRID( uuid() );
|
||||||
|
res->setScore( 1.0 );
|
||||||
|
res->setArtist( Tomahawk::artist_ptr( new Tomahawk::Artist( 0, origquery->artist() ) ) );
|
||||||
|
res->setAlbum( Tomahawk::album_ptr( new Tomahawk::Album( 0, origquery->album(), res->artist() ) ) );
|
||||||
|
res->setTrack( origquery->track() );
|
||||||
|
res->setDuration( origquery->duration() );
|
||||||
|
res->setFriendlySource( url );
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -64,7 +64,7 @@ public:
|
|||||||
QVariantMap album( int id );
|
QVariantMap album( int id );
|
||||||
QVariantMap track( int id );
|
QVariantMap track( int id );
|
||||||
Tomahawk::result_ptr file( int fid );
|
Tomahawk::result_ptr file( int fid );
|
||||||
Tomahawk::result_ptr result( const QString& url );
|
Tomahawk::result_ptr resultFromHint( const Tomahawk::query_ptr& query );
|
||||||
|
|
||||||
static bool scorepairSorter( const QPair<int,float>& left, const QPair<int,float>& right )
|
static bool scorepairSorter( const QPair<int,float>& left, const QPair<int,float>& right )
|
||||||
{
|
{
|
||||||
|
61
src/libtomahawk/database/localcollection.cpp
Normal file
61
src/libtomahawk/database/localcollection.cpp
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2011 Leo Franchi <lfranchi@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.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "localcollection.h"
|
||||||
|
|
||||||
|
#include "sourcelist.h"
|
||||||
|
#include "viewmanager.h"
|
||||||
|
#include <tomahawksettings.h>
|
||||||
|
|
||||||
|
LocalCollection::LocalCollection( const Tomahawk::source_ptr& source, QObject* parent )
|
||||||
|
: DatabaseCollection( source, parent )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Tomahawk::playlist_ptr
|
||||||
|
LocalCollection::bookmarksPlaylist()
|
||||||
|
{
|
||||||
|
if( TomahawkSettings::instance()->bookmarkPlaylist().isEmpty() )
|
||||||
|
return Tomahawk::playlist_ptr();
|
||||||
|
|
||||||
|
return playlist( TomahawkSettings::instance()->bookmarkPlaylist() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocalCollection::createBookmarksPlaylist()
|
||||||
|
{
|
||||||
|
if( bookmarksPlaylist().isNull() ) {
|
||||||
|
QString guid = uuid();
|
||||||
|
Tomahawk::playlist_ptr p = Tomahawk::Playlist::create( SourceList::instance()->getLocal(), guid, tr( "Bookmarks" ), tr( "Saved tracks" ), QString(), false );
|
||||||
|
ViewManager::instance()->createPageForPlaylist( p );
|
||||||
|
// connect( p.data(), SIGNAL( revisionLoaded( Tomahawk::PlaylistRevision ) ), this, SLOT( loaded( Tomahawk::PlaylistRevision ) ), Qt::QueuedConnection );
|
||||||
|
connect( p.data(), SIGNAL( created() ), this, SLOT( created() ) );
|
||||||
|
|
||||||
|
TomahawkSettings::instance()->setBookmarkPlaylist( guid );
|
||||||
|
// p->createNewRevision( uuid(), p->currentrevision(), QList< Tomahawk::plentry_ptr >() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocalCollection::created()
|
||||||
|
{
|
||||||
|
emit bookmarkPlaylistCreated( bookmarksPlaylist() );
|
||||||
|
}
|
46
src/libtomahawk/database/localcollection.h
Normal file
46
src/libtomahawk/database/localcollection.h
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2011 Leo Franchi <lfranchi@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.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef LOCALCOLLECTION_H
|
||||||
|
#define LOCALCOLLECTION_H
|
||||||
|
|
||||||
|
#include "databasecollection.h"
|
||||||
|
#include "dllmacro.h"
|
||||||
|
#include "playlist.h"
|
||||||
|
|
||||||
|
class DLLEXPORT LocalCollection : public DatabaseCollection
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit LocalCollection( const Tomahawk::source_ptr& source, QObject* parent = 0 );
|
||||||
|
|
||||||
|
// gets the playlist used for storing stuff from the web, if it already exists. if the returned playlist
|
||||||
|
// is invalid ask to create and listen to the signal
|
||||||
|
Tomahawk::playlist_ptr bookmarksPlaylist();
|
||||||
|
void createBookmarksPlaylist();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void bookmarkPlaylistCreated( const Tomahawk::playlist_ptr& p );
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void created();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LOCALCOLLECTION_H
|
@@ -25,13 +25,16 @@ using namespace Echonest;
|
|||||||
|
|
||||||
// for internal neatness
|
// for internal neatness
|
||||||
|
|
||||||
EchoNestPlugin::EchoNestPlugin(QObject *parent)
|
EchoNestPlugin::EchoNestPlugin(InfoSystemWorker *parent)
|
||||||
: InfoPlugin(parent)
|
: InfoPlugin(parent)
|
||||||
|
, m_infoSystemWorker( parent )
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
QSet< InfoType > supportedTypes;
|
QSet< InfoType > supportedTypes;
|
||||||
supportedTypes << Tomahawk::InfoSystem::InfoArtistBiography << Tomahawk::InfoSystem::InfoArtistFamiliarity << Tomahawk::InfoSystem::InfoArtistHotttness << Tomahawk::InfoSystem::InfoArtistTerms << Tomahawk::InfoSystem::InfoMiscTopTerms;
|
supportedTypes << Tomahawk::InfoSystem::InfoArtistBiography << Tomahawk::InfoSystem::InfoArtistFamiliarity << Tomahawk::InfoSystem::InfoArtistHotttness << Tomahawk::InfoSystem::InfoArtistTerms << Tomahawk::InfoSystem::InfoMiscTopTerms;
|
||||||
qobject_cast< InfoSystem* >(parent)->registerInfoTypes(this, supportedTypes);
|
parent->registerInfoTypes( this, supportedTypes, QSet< InfoType>() );
|
||||||
|
|
||||||
|
connect( parent, SIGNAL( namChanged() ), SLOT( namChangedSlot() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
EchoNestPlugin::~EchoNestPlugin()
|
EchoNestPlugin::~EchoNestPlugin()
|
||||||
@@ -39,6 +42,13 @@ EchoNestPlugin::~EchoNestPlugin()
|
|||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
EchoNestPlugin::namChangedSlot()
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
Echonest::Config::instance()->setNetworkAccessManager( m_infoSystemWorker->nam() );
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
EchoNestPlugin::getInfo(const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData)
|
EchoNestPlugin::getInfo(const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData)
|
||||||
{
|
{
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#define ECHONESTPLUGIN_H
|
#define ECHONESTPLUGIN_H
|
||||||
|
|
||||||
#include "infosystem/infosystem.h"
|
#include "infosystem/infosystem.h"
|
||||||
|
#include "infosystem/infosystemworker.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
@@ -39,12 +40,31 @@ class EchoNestPlugin : public InfoPlugin
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
EchoNestPlugin(QObject *parent);
|
EchoNestPlugin( InfoSystemWorker *parent );
|
||||||
virtual ~EchoNestPlugin();
|
virtual ~EchoNestPlugin();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData );
|
virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData );
|
||||||
|
|
||||||
|
virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data )
|
||||||
|
{
|
||||||
|
Q_UNUSED( caller );
|
||||||
|
Q_UNUSED( type );
|
||||||
|
Q_UNUSED( data );
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData )
|
||||||
|
{
|
||||||
|
Q_UNUSED( criteria );
|
||||||
|
Q_UNUSED( caller );
|
||||||
|
Q_UNUSED( type );
|
||||||
|
Q_UNUSED( input );
|
||||||
|
Q_UNUSED( customData );
|
||||||
|
}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void namChangedSlot();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void getSongProfile( const QString &caller, const QVariant &input, const InfoCustomData &customData, const QString &item = QString() );
|
void getSongProfile( const QString &caller, const QVariant &input, const InfoCustomData &customData, const QString &item = QString() );
|
||||||
void getArtistBiography ( const QString &caller, const QVariant &input, const InfoCustomData &customData );
|
void getArtistBiography ( const QString &caller, const QVariant &input, const InfoCustomData &customData );
|
||||||
@@ -67,6 +87,7 @@ private slots:
|
|||||||
private:
|
private:
|
||||||
QHash< QNetworkReply*, InfoCustomData > m_replyMap;
|
QHash< QNetworkReply*, InfoCustomData > m_replyMap;
|
||||||
QHash< QNetworkReply*, QString > m_callerMap;
|
QHash< QNetworkReply*, QString > m_callerMap;
|
||||||
|
InfoSystemWorker* m_infoSystemWorker;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -41,14 +41,18 @@ md5( const QByteArray& src )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LastFmPlugin::LastFmPlugin( QObject* parent )
|
LastFmPlugin::LastFmPlugin( InfoSystemWorker* parent )
|
||||||
: InfoPlugin(parent)
|
: InfoPlugin(parent)
|
||||||
, m_scrobbler( 0 )
|
, m_scrobbler( 0 )
|
||||||
, m_authJob( 0 )
|
, m_authJob( 0 )
|
||||||
|
, m_infoSystemWorker( parent )
|
||||||
{
|
{
|
||||||
QSet< InfoType > supportedTypes;
|
QSet< InfoType > supportedGetTypes, supportedPushTypes;
|
||||||
supportedTypes << InfoMiscSubmitScrobble << InfoMiscSubmitNowPlaying << InfoAlbumCoverArt << InfoArtistImages;
|
supportedGetTypes << InfoAlbumCoverArt << InfoArtistImages;
|
||||||
qobject_cast< InfoSystem* >(parent)->registerInfoTypes(this, supportedTypes);
|
supportedPushTypes << InfoSubmitScrobble << InfoSubmitNowPlaying;
|
||||||
|
parent->registerInfoTypes( this, supportedGetTypes, supportedPushTypes );
|
||||||
|
|
||||||
|
connect( parent, SIGNAL( namChanged() ), SLOT( namChangedSlot() ) );
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Your API Key is 7194b85b6d1f424fe1668173a78c0c4a
|
Your API Key is 7194b85b6d1f424fe1668173a78c0c4a
|
||||||
@@ -94,6 +98,14 @@ LastFmPlugin::~LastFmPlugin()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
LastFmPlugin::namChangedSlot()
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
lastfm::setNetworkAccessManager( m_infoSystemWorker->nam() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LastFmPlugin::dataError( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData )
|
LastFmPlugin::dataError( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData )
|
||||||
{
|
{
|
||||||
@@ -109,14 +121,6 @@ LastFmPlugin::getInfo( const QString caller, const Tomahawk::InfoSystem::InfoTyp
|
|||||||
|
|
||||||
switch ( type )
|
switch ( type )
|
||||||
{
|
{
|
||||||
case InfoMiscSubmitNowPlaying:
|
|
||||||
nowPlaying( caller, type, input, customData );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case InfoMiscSubmitScrobble:
|
|
||||||
scrobble( caller, type, input, customData );
|
|
||||||
break;
|
|
||||||
|
|
||||||
case InfoArtistImages:
|
case InfoArtistImages:
|
||||||
fetchArtistImages( caller, type, input, customData );
|
fetchArtistImages( caller, type, input, customData );
|
||||||
break;
|
break;
|
||||||
@@ -132,19 +136,34 @@ LastFmPlugin::getInfo( const QString caller, const Tomahawk::InfoSystem::InfoTyp
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LastFmPlugin::nowPlaying( const QString &caller, const InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData )
|
LastFmPlugin::pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input )
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
|
switch ( type )
|
||||||
|
{
|
||||||
|
case InfoSubmitNowPlaying:
|
||||||
|
nowPlaying( caller, type, input );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case InfoSubmitScrobble:
|
||||||
|
scrobble( caller, type, input );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LastFmPlugin::nowPlaying( const QString &caller, const InfoType type, const QVariant &input )
|
||||||
{
|
{
|
||||||
if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() || !m_scrobbler )
|
if ( !input.canConvert< Tomahawk::InfoSystem::InfoCriteriaHash >() || !m_scrobbler )
|
||||||
{
|
|
||||||
dataError( caller, type, input, customData );
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
|
InfoCriteriaHash hash = input.value< Tomahawk::InfoSystem::InfoCriteriaHash >();
|
||||||
if ( !hash.contains( "title" ) || !hash.contains( "artist" ) || !hash.contains( "album" ) || !hash.contains( "duration" ) )
|
if ( !hash.contains( "title" ) || !hash.contains( "artist" ) || !hash.contains( "album" ) || !hash.contains( "duration" ) )
|
||||||
{
|
|
||||||
dataError( caller, type, input, customData );
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
m_track = lastfm::MutableTrack();
|
m_track = lastfm::MutableTrack();
|
||||||
m_track.stamp();
|
m_track.stamp();
|
||||||
@@ -157,26 +176,20 @@ LastFmPlugin::nowPlaying( const QString &caller, const InfoType type, const QVar
|
|||||||
m_track.setSource( lastfm::Track::Player );
|
m_track.setSource( lastfm::Track::Player );
|
||||||
|
|
||||||
m_scrobbler->nowPlaying( m_track );
|
m_scrobbler->nowPlaying( m_track );
|
||||||
emit info( caller, type, input, QVariant(), customData );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LastFmPlugin::scrobble( const QString &caller, const InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData )
|
LastFmPlugin::scrobble( const QString &caller, const InfoType type, const QVariant &input )
|
||||||
{
|
{
|
||||||
Q_ASSERT( QThread::currentThread() == thread() );
|
Q_ASSERT( QThread::currentThread() == thread() );
|
||||||
|
|
||||||
if ( !m_scrobbler || m_track.isNull() )
|
if ( !m_scrobbler || m_track.isNull() )
|
||||||
{
|
|
||||||
dataError( caller, type, input, customData );
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << Q_FUNC_INFO << m_track.toString();
|
qDebug() << Q_FUNC_INFO << m_track.toString();
|
||||||
m_scrobbler->cache( m_track );
|
m_scrobbler->cache( m_track );
|
||||||
m_scrobbler->submit();
|
m_scrobbler->submit();
|
||||||
|
|
||||||
emit info( caller, type, input, QVariant(), customData );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -241,7 +254,7 @@ LastFmPlugin::notInCacheSlot( const QHash<QString, QString> criteria, const QStr
|
|||||||
|
|
||||||
QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=album.imageredirect&artist=%1&album=%2&autocorrect=1&size=medium&api_key=7a90f6672a04b809ee309af169f34b8b";
|
QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=album.imageredirect&artist=%1&album=%2&autocorrect=1&size=medium&api_key=7a90f6672a04b809ee309af169f34b8b";
|
||||||
QNetworkRequest req( imgurl.arg( artistName ).arg( albumName ) );
|
QNetworkRequest req( imgurl.arg( artistName ).arg( albumName ) );
|
||||||
QNetworkReply* reply = TomahawkUtils::nam()->get( req );
|
QNetworkReply* reply = m_infoSystemWorker->nam()->get( req );
|
||||||
reply->setProperty( "customData", QVariant::fromValue<Tomahawk::InfoSystem::InfoCustomData>( customData ) );
|
reply->setProperty( "customData", QVariant::fromValue<Tomahawk::InfoSystem::InfoCustomData>( customData ) );
|
||||||
reply->setProperty( "origData", input );
|
reply->setProperty( "origData", input );
|
||||||
reply->setProperty( "caller", caller );
|
reply->setProperty( "caller", caller );
|
||||||
@@ -257,7 +270,7 @@ LastFmPlugin::notInCacheSlot( const QHash<QString, QString> criteria, const QStr
|
|||||||
|
|
||||||
QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=artist.imageredirect&artist=%1&autocorrect=1&size=medium&api_key=7a90f6672a04b809ee309af169f34b8b";
|
QString imgurl = "http://ws.audioscrobbler.com/2.0/?method=artist.imageredirect&artist=%1&autocorrect=1&size=medium&api_key=7a90f6672a04b809ee309af169f34b8b";
|
||||||
QNetworkRequest req( imgurl.arg( artistName ) );
|
QNetworkRequest req( imgurl.arg( artistName ) );
|
||||||
QNetworkReply* reply = TomahawkUtils::nam()->get( req );
|
QNetworkReply* reply = m_infoSystemWorker->nam()->get( req );
|
||||||
reply->setProperty( "customData", QVariant::fromValue<Tomahawk::InfoSystem::InfoCustomData>( customData ) );
|
reply->setProperty( "customData", QVariant::fromValue<Tomahawk::InfoSystem::InfoCustomData>( customData ) );
|
||||||
reply->setProperty( "origData", input );
|
reply->setProperty( "origData", input );
|
||||||
reply->setProperty( "caller", caller );
|
reply->setProperty( "caller", caller );
|
||||||
@@ -312,7 +325,7 @@ LastFmPlugin::coverArtReturned()
|
|||||||
{
|
{
|
||||||
// Follow HTTP redirect
|
// Follow HTTP redirect
|
||||||
QNetworkRequest req( redir );
|
QNetworkRequest req( redir );
|
||||||
QNetworkReply* newReply = TomahawkUtils::nam()->get( req );
|
QNetworkReply* newReply = m_infoSystemWorker->nam()->get( req );
|
||||||
newReply->setProperty( "origData", reply->property( "origData" ) );
|
newReply->setProperty( "origData", reply->property( "origData" ) );
|
||||||
newReply->setProperty( "customData", reply->property( "customData" ) );
|
newReply->setProperty( "customData", reply->property( "customData" ) );
|
||||||
newReply->setProperty( "caller", reply->property( "caller" ) );
|
newReply->setProperty( "caller", reply->property( "caller" ) );
|
||||||
@@ -362,7 +375,7 @@ LastFmPlugin::artistImagesReturned()
|
|||||||
{
|
{
|
||||||
// Follow HTTP redirect
|
// Follow HTTP redirect
|
||||||
QNetworkRequest req( redir );
|
QNetworkRequest req( redir );
|
||||||
QNetworkReply* newReply = TomahawkUtils::nam()->get( req );
|
QNetworkReply* newReply = m_infoSystemWorker->nam()->get( req );
|
||||||
newReply->setProperty( "origData", reply->property( "origData" ) );
|
newReply->setProperty( "origData", reply->property( "origData" ) );
|
||||||
newReply->setProperty( "customData", reply->property( "customData" ) );
|
newReply->setProperty( "customData", reply->property( "customData" ) );
|
||||||
newReply->setProperty( "caller", reply->property( "caller" ) );
|
newReply->setProperty( "caller", reply->property( "caller" ) );
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#ifndef LASTFMPLUGIN_H
|
#ifndef LASTFMPLUGIN_H
|
||||||
#define LASTFMPLUGIN_H
|
#define LASTFMPLUGIN_H
|
||||||
#include "infosystem/infosystem.h"
|
#include "infosystem/infosystem.h"
|
||||||
|
#include "infosystem/infosystemworker.h"
|
||||||
#include "result.h"
|
#include "result.h"
|
||||||
|
|
||||||
#include <lastfm/Track>
|
#include <lastfm/Track>
|
||||||
@@ -40,7 +41,7 @@ class LastFmPlugin : public InfoPlugin
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LastFmPlugin( QObject *parent );
|
LastFmPlugin( InfoSystemWorker *parent );
|
||||||
virtual ~LastFmPlugin();
|
virtual ~LastFmPlugin();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
@@ -50,17 +51,21 @@ public slots:
|
|||||||
void coverArtReturned();
|
void coverArtReturned();
|
||||||
void artistImagesReturned();
|
void artistImagesReturned();
|
||||||
|
|
||||||
|
void namChangedSlot();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData );
|
virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData );
|
||||||
virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData );
|
virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData );
|
||||||
|
|
||||||
|
virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void fetchCoverArt( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData );
|
void fetchCoverArt( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData );
|
||||||
void fetchArtistImages( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData );
|
void fetchArtistImages( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData );
|
||||||
|
|
||||||
void createScrobbler();
|
void createScrobbler();
|
||||||
void scrobble( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData );
|
void scrobble( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input );
|
||||||
void nowPlaying( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData );
|
void nowPlaying( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input );
|
||||||
|
|
||||||
void dataError( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData );
|
void dataError( const QString &caller, const Tomahawk::InfoSystem::InfoType type, const QVariant &input, const Tomahawk::InfoSystem::InfoCustomData &customData );
|
||||||
|
|
||||||
@@ -71,6 +76,8 @@ private:
|
|||||||
QList< QUrl > m_badUrls;
|
QList< QUrl > m_badUrls;
|
||||||
|
|
||||||
QNetworkReply* m_authJob;
|
QNetworkReply* m_authJob;
|
||||||
|
|
||||||
|
InfoSystemWorker* m_infoSystemWorker;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -27,14 +27,15 @@ using namespace Tomahawk::InfoSystem;
|
|||||||
|
|
||||||
// for internal neatness
|
// for internal neatness
|
||||||
|
|
||||||
MusixMatchPlugin::MusixMatchPlugin(QObject *parent)
|
MusixMatchPlugin::MusixMatchPlugin(InfoSystemWorker *parent)
|
||||||
: InfoPlugin(parent)
|
: InfoPlugin(parent)
|
||||||
, m_apiKey("61be4ea5aea7dd942d52b2f1311dd9fe")
|
, m_apiKey("61be4ea5aea7dd942d52b2f1311dd9fe")
|
||||||
|
, m_infoSystemWorker( parent )
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
QSet< InfoType > supportedTypes;
|
QSet< InfoType > supportedTypes;
|
||||||
supportedTypes << Tomahawk::InfoSystem::InfoTrackLyrics;
|
supportedTypes << Tomahawk::InfoSystem::InfoTrackLyrics;
|
||||||
qobject_cast< InfoSystem* >(parent)->registerInfoTypes(this, supportedTypes);
|
parent->registerInfoTypes( this, supportedTypes, QSet< InfoType>() );
|
||||||
}
|
}
|
||||||
|
|
||||||
MusixMatchPlugin::~MusixMatchPlugin()
|
MusixMatchPlugin::~MusixMatchPlugin()
|
||||||
@@ -62,7 +63,7 @@ MusixMatchPlugin::getInfo( const QString caller, const Tomahawk::InfoSystem::Inf
|
|||||||
url.addQueryItem("apikey", m_apiKey);
|
url.addQueryItem("apikey", m_apiKey);
|
||||||
url.addQueryItem("q_artist", artist);
|
url.addQueryItem("q_artist", artist);
|
||||||
url.addQueryItem("q_track", track);
|
url.addQueryItem("q_track", track);
|
||||||
QNetworkReply* reply = TomahawkUtils::nam()->get(QNetworkRequest(url));
|
QNetworkReply* reply = m_infoSystemWorker->nam()->get(QNetworkRequest(url));
|
||||||
reply->setProperty("customData", QVariant::fromValue<Tomahawk::InfoSystem::InfoCustomData>(customData));
|
reply->setProperty("customData", QVariant::fromValue<Tomahawk::InfoSystem::InfoCustomData>(customData));
|
||||||
reply->setProperty("origData", input);
|
reply->setProperty("origData", input);
|
||||||
reply->setProperty("caller", caller);
|
reply->setProperty("caller", caller);
|
||||||
@@ -120,7 +121,7 @@ MusixMatchPlugin::trackSearchSlot()
|
|||||||
QUrl url(requestString);
|
QUrl url(requestString);
|
||||||
url.addQueryItem("apikey", m_apiKey);
|
url.addQueryItem("apikey", m_apiKey);
|
||||||
url.addQueryItem("track_id", track_id);
|
url.addQueryItem("track_id", track_id);
|
||||||
QNetworkReply* newReply = TomahawkUtils::nam()->get(QNetworkRequest(url));
|
QNetworkReply* newReply = m_infoSystemWorker->nam()->get(QNetworkRequest(url));
|
||||||
newReply->setProperty("origData", oldReply->property("origData"));
|
newReply->setProperty("origData", oldReply->property("origData"));
|
||||||
newReply->setProperty("customData", oldReply->property("customData"));
|
newReply->setProperty("customData", oldReply->property("customData"));
|
||||||
newReply->setProperty("caller", oldReply->property("caller"));
|
newReply->setProperty("caller", oldReply->property("caller"));
|
||||||
|
@@ -20,6 +20,7 @@
|
|||||||
#define MUSIXMATCHPLUGIN_H
|
#define MUSIXMATCHPLUGIN_H
|
||||||
|
|
||||||
#include "infosystem/infosystem.h"
|
#include "infosystem/infosystem.h"
|
||||||
|
#include "infosystem/infosystemworker.h"
|
||||||
|
|
||||||
class QNetworkReply;
|
class QNetworkReply;
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ class MusixMatchPlugin : public InfoPlugin
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MusixMatchPlugin( QObject *parent );
|
MusixMatchPlugin( InfoSystemWorker *parent );
|
||||||
virtual ~MusixMatchPlugin();
|
virtual ~MusixMatchPlugin();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
@@ -43,11 +44,29 @@ public slots:
|
|||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData );
|
virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData );
|
||||||
|
|
||||||
|
virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data )
|
||||||
|
{
|
||||||
|
Q_UNUSED( caller );
|
||||||
|
Q_UNUSED( type );
|
||||||
|
Q_UNUSED( data );
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData )
|
||||||
|
{
|
||||||
|
Q_UNUSED( criteria );
|
||||||
|
Q_UNUSED( caller );
|
||||||
|
Q_UNUSED( type );
|
||||||
|
Q_UNUSED( input );
|
||||||
|
Q_UNUSED( customData );
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool isValidTrackData( const QString &caller, const QVariant &input, const InfoCustomData &customData );
|
bool isValidTrackData( const QString &caller, const QVariant &input, const InfoCustomData &customData );
|
||||||
|
|
||||||
QString m_apiKey;
|
QString m_apiKey;
|
||||||
|
|
||||||
|
InfoSystemWorker* m_infoSystemWorker;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -19,6 +19,7 @@
|
|||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
|
||||||
#include "infosystem.h"
|
#include "infosystem.h"
|
||||||
|
#include "tomahawksettings.h"
|
||||||
#include "utils/tomahawkutils.h"
|
#include "utils/tomahawkutils.h"
|
||||||
#include "infosystemcache.h"
|
#include "infosystemcache.h"
|
||||||
#include "infoplugins/echonestplugin.h"
|
#include "infoplugins/echonestplugin.h"
|
||||||
@@ -31,11 +32,11 @@ namespace Tomahawk
|
|||||||
namespace InfoSystem
|
namespace InfoSystem
|
||||||
{
|
{
|
||||||
|
|
||||||
InfoPlugin::InfoPlugin(QObject *parent)
|
InfoPlugin::InfoPlugin( InfoSystemWorker *parent )
|
||||||
:QObject( parent )
|
:QObject( parent )
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
InfoSystem* InfoSystem::s_instance = 0;
|
InfoSystem* InfoSystem::s_instance = 0;
|
||||||
@@ -59,59 +60,33 @@ InfoSystem::InfoSystem(QObject *parent)
|
|||||||
m_cache->moveToThread( m_infoSystemCacheThreadController );
|
m_cache->moveToThread( m_infoSystemCacheThreadController );
|
||||||
m_infoSystemCacheThreadController->start( QThread::IdlePriority );
|
m_infoSystemCacheThreadController->start( QThread::IdlePriority );
|
||||||
|
|
||||||
InfoPluginPtr enptr( new EchoNestPlugin( this ) );
|
m_infoSystemWorkerThreadController = new QThread( this );
|
||||||
m_plugins.append( enptr );
|
m_worker = new InfoSystemWorker();
|
||||||
InfoPluginPtr mmptr( new MusixMatchPlugin( this ) );
|
m_worker->moveToThread( m_infoSystemWorkerThreadController );
|
||||||
m_plugins.append( mmptr );
|
m_infoSystemWorkerThreadController->start();
|
||||||
InfoPluginPtr lfmptr( new LastFmPlugin( this ) );
|
|
||||||
m_plugins.append( lfmptr );
|
|
||||||
|
|
||||||
Q_FOREACH( InfoPluginPtr plugin, m_plugins )
|
QMetaObject::invokeMethod( m_worker, "init", Qt::QueuedConnection );
|
||||||
{
|
|
||||||
connect(
|
connect( TomahawkSettings::instance(), SIGNAL( changed() ), SLOT( newNam() ) );
|
||||||
plugin.data(),
|
|
||||||
SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
|
||||||
this,
|
|
||||||
SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
|
||||||
Qt::UniqueConnection
|
|
||||||
);
|
|
||||||
|
|
||||||
connect(
|
|
||||||
plugin.data(),
|
|
||||||
SIGNAL( getCachedInfo( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
|
||||||
m_cache,
|
|
||||||
SLOT( getCachedInfoSlot( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) )
|
|
||||||
);
|
|
||||||
connect(
|
|
||||||
m_cache,
|
|
||||||
SIGNAL( notInCache( Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
|
||||||
plugin.data(),
|
|
||||||
SLOT( notInCacheSlot( Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) )
|
|
||||||
);
|
|
||||||
connect(
|
|
||||||
plugin.data(),
|
|
||||||
SIGNAL( updateCache( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) ),
|
|
||||||
m_cache,
|
|
||||||
SLOT( updateCacheSlot( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
connect( m_cache, SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
connect( m_cache, SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
||||||
this, SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), Qt::UniqueConnection );
|
this, SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), Qt::UniqueConnection );
|
||||||
|
|
||||||
|
connect( m_worker, SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
||||||
|
this, SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ), Qt::UniqueConnection );
|
||||||
}
|
}
|
||||||
|
|
||||||
InfoSystem::~InfoSystem()
|
InfoSystem::~InfoSystem()
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
Q_FOREACH( InfoPluginPtr plugin, m_plugins )
|
|
||||||
{
|
|
||||||
if( plugin )
|
|
||||||
delete plugin.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if ( m_infoSystemCacheThreadController )
|
||||||
|
m_infoSystemCacheThreadController->quit();
|
||||||
|
if ( m_infoSystemWorkerThreadController )
|
||||||
|
m_infoSystemWorkerThreadController->quit();
|
||||||
|
|
||||||
if( m_infoSystemCacheThreadController )
|
if( m_infoSystemCacheThreadController )
|
||||||
{
|
{
|
||||||
m_infoSystemCacheThreadController->quit();
|
|
||||||
|
|
||||||
while( !m_infoSystemCacheThreadController->isFinished() )
|
while( !m_infoSystemCacheThreadController->isFinished() )
|
||||||
{
|
{
|
||||||
QCoreApplication::processEvents( QEventLoop::AllEvents, 200 );
|
QCoreApplication::processEvents( QEventLoop::AllEvents, 200 );
|
||||||
@@ -127,56 +102,73 @@ InfoSystem::~InfoSystem()
|
|||||||
delete m_infoSystemCacheThreadController;
|
delete m_infoSystemCacheThreadController;
|
||||||
m_infoSystemCacheThreadController = 0;
|
m_infoSystemCacheThreadController = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( m_infoSystemWorkerThreadController )
|
||||||
|
{
|
||||||
|
while( !m_infoSystemWorkerThreadController->isFinished() )
|
||||||
|
{
|
||||||
|
QCoreApplication::processEvents( QEventLoop::AllEvents, 200 );
|
||||||
|
TomahawkUtils::Sleep::msleep( 100 );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_worker )
|
||||||
|
{
|
||||||
|
delete m_worker;
|
||||||
|
m_worker = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete m_infoSystemWorkerThreadController;
|
||||||
|
m_infoSystemWorkerThreadController = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InfoSystem::registerInfoTypes(const InfoPluginPtr &plugin, const QSet< InfoType >& types)
|
|
||||||
|
void
|
||||||
|
InfoSystem::newNam() const
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
Q_FOREACH(InfoType type, types)
|
QMetaObject::invokeMethod( m_worker, "newNam", Qt::QueuedConnection );
|
||||||
m_infoMap[type].append(plugin);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QLinkedList< InfoPluginPtr > InfoSystem::determineOrderedMatches(const InfoType type) const
|
|
||||||
{
|
|
||||||
//Dummy function for now that returns the various items in the QSet; at some point this will
|
|
||||||
//probably need to support ordering based on the data source
|
|
||||||
QLinkedList< InfoPluginPtr > providers;
|
|
||||||
Q_FOREACH(InfoPluginPtr ptr, m_infoMap[type])
|
|
||||||
providers << ptr;
|
|
||||||
return providers;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InfoSystem::getInfo(const QString &caller, const InfoType type, const QVariant& input, InfoCustomData customData)
|
void
|
||||||
|
InfoSystem::getInfo( const QString &caller, const InfoType type, const QVariant& input, InfoCustomData customData )
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
QLinkedList< InfoPluginPtr > providers = determineOrderedMatches(type);
|
|
||||||
if (providers.isEmpty())
|
|
||||||
{
|
|
||||||
emit info(caller, InfoNoInfo, QVariant(), QVariant(), customData);
|
|
||||||
emit finished(caller);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
InfoPluginPtr ptr = providers.first();
|
|
||||||
if (!ptr)
|
|
||||||
{
|
|
||||||
emit info(caller, InfoNoInfo, QVariant(), QVariant(), customData);
|
|
||||||
emit finished(caller);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_dataTracker[caller][type] = m_dataTracker[caller][type] + 1;
|
m_dataTracker[caller][type] = m_dataTracker[caller][type] + 1;
|
||||||
qDebug() << "current count in dataTracker for type" << type << "is" << m_dataTracker[caller][type];
|
qDebug() << "current count in dataTracker for type" << type << "is" << m_dataTracker[caller][type];
|
||||||
QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( Tomahawk::InfoSystem::InfoCustomData, customData ) );
|
QMetaObject::invokeMethod( m_worker, "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( Tomahawk::InfoSystem::InfoCustomData, customData ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void InfoSystem::getInfo(const QString &caller, const InfoMap &input, InfoCustomData customData)
|
|
||||||
|
void
|
||||||
|
InfoSystem::getInfo( const QString &caller, const InfoMap &input, InfoCustomData customData )
|
||||||
{
|
{
|
||||||
Q_FOREACH( InfoType type, input.keys() )
|
Q_FOREACH( InfoType type, input.keys() )
|
||||||
getInfo(caller, type, input[type], customData);
|
getInfo( caller, type, input[type], customData );
|
||||||
}
|
}
|
||||||
|
|
||||||
void InfoSystem::infoSlot(QString target, InfoType type, QVariant input, QVariant output, InfoCustomData customData)
|
|
||||||
|
void
|
||||||
|
InfoSystem::pushInfo( const QString &caller, const InfoType type, const QVariant& input )
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod( m_worker, "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
InfoSystem::pushInfo( const QString &caller, const InfoMap &input )
|
||||||
|
{
|
||||||
|
Q_FOREACH( InfoType type, input.keys() )
|
||||||
|
pushInfo( caller, type, input[type] );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
InfoSystem::infoSlot( QString target, InfoType type, QVariant input, QVariant output, InfoCustomData customData )
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
qDebug() << "current count in dataTracker is " << m_dataTracker[target][type];
|
qDebug() << "current count in dataTracker is " << m_dataTracker[target][type];
|
||||||
|
@@ -36,62 +36,63 @@ namespace Tomahawk {
|
|||||||
namespace InfoSystem {
|
namespace InfoSystem {
|
||||||
|
|
||||||
class InfoSystemCache;
|
class InfoSystemCache;
|
||||||
|
class InfoSystemWorker;
|
||||||
|
|
||||||
enum InfoType {
|
enum InfoType { // as items are saved in cache, mark them here to not change them
|
||||||
InfoTrackID = 0,
|
InfoTrackID = 0,
|
||||||
InfoTrackArtist,
|
InfoTrackArtist = 1,
|
||||||
InfoTrackAlbum,
|
InfoTrackAlbum = 2,
|
||||||
InfoTrackGenre,
|
InfoTrackGenre = 3,
|
||||||
InfoTrackComposer,
|
InfoTrackComposer = 4,
|
||||||
InfoTrackDate,
|
InfoTrackDate = 5,
|
||||||
InfoTrackNumber,
|
InfoTrackNumber = 6,
|
||||||
InfoTrackDiscNumber,
|
InfoTrackDiscNumber = 7,
|
||||||
InfoTrackBitRate,
|
InfoTrackBitRate = 8,
|
||||||
InfoTrackLength,
|
InfoTrackLength = 9,
|
||||||
InfoTrackSampleRate,
|
InfoTrackSampleRate = 10,
|
||||||
InfoTrackFileSize,
|
InfoTrackFileSize = 11,
|
||||||
InfoTrackBPM,
|
InfoTrackBPM = 12,
|
||||||
InfoTrackReplayGain,
|
InfoTrackReplayGain = 13,
|
||||||
InfoTrackReplayPeakGain,
|
InfoTrackReplayPeakGain = 14,
|
||||||
InfoTrackLyrics,
|
InfoTrackLyrics = 15,
|
||||||
InfoTrackLocation,
|
InfoTrackLocation = 16,
|
||||||
InfoTrackProfile,
|
InfoTrackProfile = 17,
|
||||||
InfoTrackEnergy,
|
InfoTrackEnergy = 18,
|
||||||
InfoTrackDanceability,
|
InfoTrackDanceability = 19,
|
||||||
InfoTrackTempo,
|
InfoTrackTempo = 20,
|
||||||
InfoTrackLoudness,
|
InfoTrackLoudness = 21,
|
||||||
|
|
||||||
InfoArtistID,
|
InfoArtistID = 22,
|
||||||
InfoArtistName,
|
InfoArtistName = 23,
|
||||||
InfoArtistBiography,
|
InfoArtistBiography = 24,
|
||||||
InfoArtistBlog,
|
InfoArtistBlog = 25,
|
||||||
InfoArtistFamiliarity,
|
InfoArtistFamiliarity = 26,
|
||||||
InfoArtistHotttness,
|
InfoArtistHotttness = 27,
|
||||||
InfoArtistImages,
|
InfoArtistImages = 28,
|
||||||
InfoArtistNews,
|
InfoArtistNews = 29,
|
||||||
InfoArtistProfile,
|
InfoArtistProfile = 30,
|
||||||
InfoArtistReviews,
|
InfoArtistReviews = 31,
|
||||||
InfoArtistSongs,
|
InfoArtistSongs = 32,
|
||||||
InfoArtistSimilars,
|
InfoArtistSimilars = 33,
|
||||||
InfoArtistTerms,
|
InfoArtistTerms = 34,
|
||||||
InfoArtistLinks,
|
InfoArtistLinks = 35,
|
||||||
InfoArtistVideos,
|
InfoArtistVideos = 36,
|
||||||
|
|
||||||
InfoAlbumID,
|
InfoAlbumID = 37,
|
||||||
InfoAlbumName,
|
InfoAlbumName = 38,
|
||||||
InfoAlbumArtist,
|
InfoAlbumArtist = 39,
|
||||||
InfoAlbumDate,
|
InfoAlbumDate = 40,
|
||||||
InfoAlbumGenre,
|
InfoAlbumGenre = 41,
|
||||||
InfoAlbumComposer,
|
InfoAlbumComposer = 42,
|
||||||
InfoAlbumCoverArt,
|
InfoAlbumCoverArt = 43, //cached -- do not change
|
||||||
|
|
||||||
InfoMiscTopHotttness,
|
InfoMiscTopHotttness = 44,
|
||||||
InfoMiscTopTerms,
|
InfoMiscTopTerms = 45,
|
||||||
|
|
||||||
InfoMiscSubmitNowPlaying,
|
InfoSubmitNowPlaying = 46,
|
||||||
InfoMiscSubmitScrobble,
|
InfoSubmitScrobble = 47,
|
||||||
|
|
||||||
InfoNoInfo
|
InfoNoInfo = 48
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef QMap< InfoType, QVariant > InfoMap;
|
typedef QMap< InfoType, QVariant > InfoMap;
|
||||||
@@ -104,12 +105,9 @@ class DLLEXPORT InfoPlugin : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
InfoPlugin( QObject *parent );
|
InfoPlugin( InfoSystemWorker *parent );
|
||||||
|
|
||||||
virtual ~InfoPlugin()
|
virtual ~InfoPlugin() {}
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
}
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void getCachedInfo( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData );
|
void getCachedInfo( Tomahawk::InfoSystem::InfoCriteriaHash criteria, qint64 newMaxAge, QString caller, Tomahawk::InfoSystem::InfoType type, QVariant input, Tomahawk::InfoSystem::InfoCustomData customData );
|
||||||
@@ -119,16 +117,8 @@ signals:
|
|||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data, const Tomahawk::InfoSystem::InfoCustomData customData ) = 0;
|
virtual void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data, const Tomahawk::InfoSystem::InfoCustomData customData ) = 0;
|
||||||
|
virtual void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant data ) = 0;
|
||||||
//FIXME: Make pure virtual when everything supports it
|
virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData ) = 0;
|
||||||
virtual void notInCacheSlot( const Tomahawk::InfoSystem::InfoCriteriaHash criteria, const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData )
|
|
||||||
{
|
|
||||||
Q_UNUSED( criteria );
|
|
||||||
Q_UNUSED( caller );
|
|
||||||
Q_UNUSED( type );
|
|
||||||
Q_UNUSED( input );
|
|
||||||
Q_UNUSED( customData );
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
InfoType m_type;
|
InfoType m_type;
|
||||||
@@ -139,13 +129,6 @@ private:
|
|||||||
|
|
||||||
typedef QWeakPointer< InfoPlugin > InfoPluginPtr;
|
typedef QWeakPointer< InfoPlugin > InfoPluginPtr;
|
||||||
|
|
||||||
class DLLEXPORT InfoSystemWorker : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
InfoSystemWorker() {};
|
|
||||||
~InfoSystemWorker() {};
|
|
||||||
};
|
|
||||||
|
|
||||||
class DLLEXPORT InfoSystem : public QObject
|
class DLLEXPORT InfoSystem : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -156,12 +139,12 @@ public:
|
|||||||
InfoSystem( QObject *parent );
|
InfoSystem( QObject *parent );
|
||||||
~InfoSystem();
|
~InfoSystem();
|
||||||
|
|
||||||
void registerInfoTypes( const InfoPluginPtr &plugin, const QSet< InfoType > &types );
|
|
||||||
|
|
||||||
void getInfo( const QString &caller, const InfoType type, const QVariant &input, InfoCustomData customData );
|
void getInfo( const QString &caller, const InfoType type, const QVariant &input, InfoCustomData customData );
|
||||||
void getInfo( const QString &caller, const InfoMap &input, InfoCustomData customData );
|
void getInfo( const QString &caller, const InfoMap &input, InfoCustomData customData );
|
||||||
|
void pushInfo( const QString &caller, const InfoType type, const QVariant &input );
|
||||||
|
void pushInfo( const QString &caller, const InfoMap &input );
|
||||||
|
|
||||||
InfoSystemCache* getCache() { return m_cache; }
|
InfoSystemCache* getCache() const { return m_cache; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void info( QString caller, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData );
|
void info( QString caller, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData );
|
||||||
@@ -170,14 +153,9 @@ signals:
|
|||||||
public slots:
|
public slots:
|
||||||
void infoSlot( const QString target, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariant output, const Tomahawk::InfoSystem::InfoCustomData customData );
|
void infoSlot( const QString target, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const QVariant output, const Tomahawk::InfoSystem::InfoCustomData customData );
|
||||||
|
|
||||||
|
void newNam() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QLinkedList< InfoPluginPtr > determineOrderedMatches( const InfoType type ) const;
|
|
||||||
|
|
||||||
QMap< InfoType, QLinkedList< InfoPluginPtr > > m_infoMap;
|
|
||||||
|
|
||||||
// For now, statically instantiate plugins; this is just somewhere to keep them
|
|
||||||
QLinkedList< InfoPluginPtr > m_plugins;
|
|
||||||
|
|
||||||
QHash< QString, QHash< InfoType, int > > m_dataTracker;
|
QHash< QString, QHash< InfoType, int > > m_dataTracker;
|
||||||
|
|
||||||
InfoSystemCache* m_cache;
|
InfoSystemCache* m_cache;
|
||||||
|
190
src/libtomahawk/infosystem/infosystemworker.cpp
Normal file
190
src/libtomahawk/infosystem/infosystemworker.cpp
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
*
|
||||||
|
* 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 <QCoreApplication>
|
||||||
|
#include <QNetworkConfiguration>
|
||||||
|
#include <QNetworkProxy>
|
||||||
|
|
||||||
|
#include "infosystemworker.h"
|
||||||
|
#include "utils/tomahawkutils.h"
|
||||||
|
#include "infosystemcache.h"
|
||||||
|
#include "infoplugins/echonestplugin.h"
|
||||||
|
#include "infoplugins/musixmatchplugin.h"
|
||||||
|
#include "infoplugins/lastfmplugin.h"
|
||||||
|
|
||||||
|
namespace Tomahawk
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace InfoSystem
|
||||||
|
{
|
||||||
|
|
||||||
|
InfoSystemWorker::InfoSystemWorker()
|
||||||
|
: m_nam( 0 )
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
InfoSystemWorker::~InfoSystemWorker()
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
Q_FOREACH( InfoPluginPtr plugin, m_plugins )
|
||||||
|
{
|
||||||
|
if( plugin )
|
||||||
|
delete plugin.data();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void InfoSystemWorker::init()
|
||||||
|
{
|
||||||
|
InfoPluginPtr enptr( new EchoNestPlugin( this ) );
|
||||||
|
m_plugins.append( enptr );
|
||||||
|
InfoPluginPtr mmptr( new MusixMatchPlugin( this ) );
|
||||||
|
m_plugins.append( mmptr );
|
||||||
|
InfoPluginPtr lfmptr( new LastFmPlugin( this ) );
|
||||||
|
m_plugins.append( lfmptr );
|
||||||
|
|
||||||
|
InfoSystemCache *cache = InfoSystem::instance()->getCache();
|
||||||
|
|
||||||
|
Q_FOREACH( InfoPluginPtr plugin, m_plugins )
|
||||||
|
{
|
||||||
|
connect(
|
||||||
|
plugin.data(),
|
||||||
|
SIGNAL( info( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
||||||
|
InfoSystem::instance(),
|
||||||
|
SLOT( infoSlot( QString, Tomahawk::InfoSystem::InfoType, QVariant, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
||||||
|
Qt::UniqueConnection
|
||||||
|
);
|
||||||
|
|
||||||
|
connect(
|
||||||
|
plugin.data(),
|
||||||
|
SIGNAL( getCachedInfo( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
||||||
|
cache,
|
||||||
|
SLOT( getCachedInfoSlot( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) )
|
||||||
|
);
|
||||||
|
connect(
|
||||||
|
cache,
|
||||||
|
SIGNAL( notInCache( Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) ),
|
||||||
|
plugin.data(),
|
||||||
|
SLOT( notInCacheSlot( Tomahawk::InfoSystem::InfoCriteriaHash, QString, Tomahawk::InfoSystem::InfoType, QVariant, Tomahawk::InfoSystem::InfoCustomData ) )
|
||||||
|
);
|
||||||
|
connect(
|
||||||
|
plugin.data(),
|
||||||
|
SIGNAL( updateCache( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) ),
|
||||||
|
cache,
|
||||||
|
SLOT( updateCacheSlot( Tomahawk::InfoSystem::InfoCriteriaHash, qint64, Tomahawk::InfoSystem::InfoType, QVariant ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod( this, "newNam" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
InfoSystemWorker::registerInfoTypes( const InfoPluginPtr &plugin, const QSet< InfoType >& getTypes, const QSet< InfoType >& pushTypes )
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
Q_FOREACH( InfoType type, getTypes )
|
||||||
|
m_infoGetMap[type].append( plugin );
|
||||||
|
Q_FOREACH( InfoType type, pushTypes )
|
||||||
|
m_infoPushMap[type].append( plugin );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QLinkedList< InfoPluginPtr >
|
||||||
|
InfoSystemWorker::determineOrderedMatches( const InfoType type ) const
|
||||||
|
{
|
||||||
|
//Dummy function for now that returns the various items in the QSet; at some point this will
|
||||||
|
//probably need to support ordering based on the data source
|
||||||
|
QLinkedList< InfoPluginPtr > providers;
|
||||||
|
Q_FOREACH( InfoPluginPtr ptr, m_infoGetMap[type] )
|
||||||
|
providers << ptr;
|
||||||
|
return providers;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
InfoSystemWorker::getInfo( QString caller, InfoType type, QVariant input, InfoCustomData customData )
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
QLinkedList< InfoPluginPtr > providers = determineOrderedMatches(type);
|
||||||
|
if ( providers.isEmpty() )
|
||||||
|
{
|
||||||
|
emit info( caller, type, QVariant(), QVariant(), customData );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoPluginPtr ptr = providers.first();
|
||||||
|
if ( !ptr )
|
||||||
|
{
|
||||||
|
emit info( caller, type, QVariant(), QVariant(), customData );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod( ptr.data(), "getInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ), Q_ARG( Tomahawk::InfoSystem::InfoCustomData, customData ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
InfoSystemWorker::pushInfo( const QString caller, const InfoType type, const QVariant input )
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
|
Q_FOREACH( InfoPluginPtr ptr, m_infoPushMap[type] )
|
||||||
|
{
|
||||||
|
if( ptr )
|
||||||
|
QMetaObject::invokeMethod( ptr.data(), "pushInfo", Qt::QueuedConnection, Q_ARG( QString, caller ), Q_ARG( Tomahawk::InfoSystem::InfoType, type ), Q_ARG( QVariant, input ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QNetworkAccessManager*
|
||||||
|
InfoSystemWorker::nam() const
|
||||||
|
{
|
||||||
|
return m_nam;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
InfoSystemWorker::newNam()
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
QNetworkAccessManager *newNam = new QNetworkAccessManager();
|
||||||
|
if ( m_nam )
|
||||||
|
{
|
||||||
|
delete m_nam;
|
||||||
|
}
|
||||||
|
QNetworkAccessManager *oldNam = TomahawkUtils::nam();
|
||||||
|
if ( !oldNam )
|
||||||
|
{
|
||||||
|
m_nam = newNam;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
newNam->setConfiguration( oldNam->configuration() );
|
||||||
|
newNam->setNetworkAccessible( oldNam->networkAccessible() );
|
||||||
|
newNam->setProxy( oldNam->proxy() );
|
||||||
|
m_nam = newNam;
|
||||||
|
|
||||||
|
emit namChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} //namespace InfoSystem
|
||||||
|
|
||||||
|
} //namespace Tomahawk
|
76
src/libtomahawk/infosystem/infosystemworker.h
Normal file
76
src/libtomahawk/infosystem/infosystemworker.h
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
|
*
|
||||||
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
*
|
||||||
|
* 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 TOMAHAWK_INFOSYSTEMWORKER_H
|
||||||
|
#define TOMAHAWK_INFOSYSTEMWORKER_H
|
||||||
|
|
||||||
|
#include "infosystem/infosystem.h"
|
||||||
|
|
||||||
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/QtDebug>
|
||||||
|
#include <QtCore/QMap>
|
||||||
|
#include <QtCore/QWeakPointer>
|
||||||
|
#include <QtCore/QSet>
|
||||||
|
#include <QtCore/QLinkedList>
|
||||||
|
#include <QtCore/QVariant>
|
||||||
|
|
||||||
|
#include "dllmacro.h"
|
||||||
|
|
||||||
|
namespace Tomahawk {
|
||||||
|
|
||||||
|
namespace InfoSystem {
|
||||||
|
|
||||||
|
class DLLEXPORT InfoSystemWorker : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
InfoSystemWorker();
|
||||||
|
~InfoSystemWorker();
|
||||||
|
|
||||||
|
void registerInfoTypes( const InfoPluginPtr &plugin, const QSet< InfoType > &getTypes, const QSet< InfoType > &pushTypes );
|
||||||
|
QNetworkAccessManager* nam() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void info( QString target, Tomahawk::InfoSystem::InfoType, QVariant input, QVariant output, Tomahawk::InfoSystem::InfoCustomData customData );
|
||||||
|
void namChanged();
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void init();
|
||||||
|
void getInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input, const Tomahawk::InfoSystem::InfoCustomData customData );
|
||||||
|
void pushInfo( const QString caller, const Tomahawk::InfoSystem::InfoType type, const QVariant input );
|
||||||
|
void newNam();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QLinkedList< InfoPluginPtr > determineOrderedMatches( const InfoType type ) const;
|
||||||
|
|
||||||
|
// For now, statically instantiate plugins; this is just somewhere to keep them
|
||||||
|
QLinkedList< InfoPluginPtr > m_plugins;
|
||||||
|
|
||||||
|
QMap< InfoType, QLinkedList< InfoPluginPtr > > m_infoGetMap;
|
||||||
|
QMap< InfoType, QLinkedList< InfoPluginPtr > > m_infoPushMap;
|
||||||
|
|
||||||
|
QNetworkAccessManager *m_nam;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TOMAHAWK_INFOSYSTEMWORKER_H
|
@@ -496,13 +496,13 @@ Servent::connectToPeer( const QString& ha, int port, const QString &key, const Q
|
|||||||
void
|
void
|
||||||
Servent::connectToPeer( const QString& ha, int port, const QString &key, Connection* conn )
|
Servent::connectToPeer( const QString& ha, int port, const QString &key, Connection* conn )
|
||||||
{
|
{
|
||||||
|
qDebug() << "Servent::connectToPeer:" << ha << ":" << port
|
||||||
|
<< thread() << QThread::currentThread();
|
||||||
|
|
||||||
Q_ASSERT( port > 0 );
|
Q_ASSERT( port > 0 );
|
||||||
Q_ASSERT( conn );
|
Q_ASSERT( conn );
|
||||||
// Q_ASSERT( this->thread() == QThread::currentThread() );
|
// Q_ASSERT( this->thread() == QThread::currentThread() );
|
||||||
|
|
||||||
qDebug() << "Servent::connectToPeer:" << ha << ":" << port
|
|
||||||
<< thread() << QThread::currentThread();
|
|
||||||
|
|
||||||
if ( ( ha == m_externalAddress.toString() || ha == m_externalHostname ) &&
|
if ( ( ha == m_externalAddress.toString() || ha == m_externalHostname ) &&
|
||||||
( port == m_externalPort ) )
|
( port == m_externalPort ) )
|
||||||
{
|
{
|
||||||
|
@@ -30,7 +30,7 @@
|
|||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
DynamicPlaylist::DynamicPlaylist(const Tomahawk::source_ptr& author, const QString& type )
|
DynamicPlaylist::DynamicPlaylist(const Tomahawk::source_ptr& author, const QString& type )
|
||||||
: Playlist(author)
|
: Playlist(author)
|
||||||
{
|
{
|
||||||
qDebug() << Q_FUNC_INFO << "JSON";
|
qDebug() << Q_FUNC_INFO << "JSON";
|
||||||
m_generator = geninterface_ptr( GeneratorFactory::create( type ) );
|
m_generator = geninterface_ptr( GeneratorFactory::create( type ) );
|
||||||
@@ -54,7 +54,7 @@ DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& src,
|
|||||||
bool shared,
|
bool shared,
|
||||||
int lastmod,
|
int lastmod,
|
||||||
const QString& guid )
|
const QString& guid )
|
||||||
: Playlist( src, currentrevision, title, info, creator, createdOn, shared, lastmod, guid )
|
: Playlist( src, currentrevision, title, info, creator, createdOn, shared, lastmod, guid )
|
||||||
{
|
{
|
||||||
qDebug() << "Creating Dynamic Playlist 1";
|
qDebug() << "Creating Dynamic Playlist 1";
|
||||||
// TODO instantiate generator
|
// TODO instantiate generator
|
||||||
@@ -72,7 +72,7 @@ DynamicPlaylist::DynamicPlaylist ( const Tomahawk::source_ptr& author,
|
|||||||
const QString& type,
|
const QString& type,
|
||||||
GeneratorMode mode,
|
GeneratorMode mode,
|
||||||
bool shared )
|
bool shared )
|
||||||
: Playlist ( author, guid, title, info, creator, shared )
|
: Playlist ( author, guid, title, info, creator, shared )
|
||||||
{
|
{
|
||||||
qDebug() << "Creating Dynamic Playlist 2";
|
qDebug() << "Creating Dynamic Playlist 2";
|
||||||
m_generator = geninterface_ptr( GeneratorFactory::create( type ) );
|
m_generator = geninterface_ptr( GeneratorFactory::create( type ) );
|
||||||
@@ -113,15 +113,15 @@ DynamicPlaylist::setMode( int mode )
|
|||||||
|
|
||||||
dynplaylist_ptr
|
dynplaylist_ptr
|
||||||
DynamicPlaylist::create( const Tomahawk::source_ptr& author,
|
DynamicPlaylist::create( const Tomahawk::source_ptr& author,
|
||||||
const QString& guid,
|
const QString& guid,
|
||||||
const QString& title,
|
const QString& title,
|
||||||
const QString& info,
|
const QString& info,
|
||||||
const QString& creator,
|
const QString& creator,
|
||||||
GeneratorMode mode,
|
GeneratorMode mode,
|
||||||
bool shared )
|
bool shared,
|
||||||
|
const QString& type
|
||||||
|
)
|
||||||
{
|
{
|
||||||
// default generator
|
|
||||||
QString type = "";
|
|
||||||
dynplaylist_ptr dynplaylist = dynplaylist_ptr( new DynamicPlaylist( author, guid, title, info, creator, type, mode, shared ) );
|
dynplaylist_ptr dynplaylist = dynplaylist_ptr( new DynamicPlaylist( author, guid, title, info, creator, type, mode, shared ) );
|
||||||
|
|
||||||
DatabaseCommand_CreateDynamicPlaylist* cmd = new DatabaseCommand_CreateDynamicPlaylist( author, dynplaylist );
|
DatabaseCommand_CreateDynamicPlaylist* cmd = new DatabaseCommand_CreateDynamicPlaylist( author, dynplaylist );
|
||||||
@@ -148,10 +148,10 @@ DynamicPlaylist::createNewRevision( const QString& newUuid )
|
|||||||
// create a new revision that will be a static playlist, as it has entries
|
// create a new revision that will be a static playlist, as it has entries
|
||||||
void
|
void
|
||||||
DynamicPlaylist::createNewRevision( const QString& newrev,
|
DynamicPlaylist::createNewRevision( const QString& newrev,
|
||||||
const QString& oldrev,
|
const QString& oldrev,
|
||||||
const QString& type,
|
const QString& type,
|
||||||
const QList< dyncontrol_ptr>& controls,
|
const QList< dyncontrol_ptr>& controls,
|
||||||
const QList< plentry_ptr >& entries )
|
const QList< plentry_ptr >& entries )
|
||||||
{
|
{
|
||||||
// get the newly added tracks
|
// get the newly added tracks
|
||||||
QList< plentry_ptr > added = newEntries( entries );
|
QList< plentry_ptr > added = newEntries( entries );
|
||||||
@@ -162,29 +162,29 @@ DynamicPlaylist::createNewRevision( const QString& newrev,
|
|||||||
|
|
||||||
// no conflict resolution or partial updating for controls. all or nothing baby
|
// no conflict resolution or partial updating for controls. all or nothing baby
|
||||||
|
|
||||||
// source making the change (local user in this case)
|
// source making the change (local user in this case)
|
||||||
source_ptr author = SourceList::instance()->getLocal();
|
source_ptr author = SourceList::instance()->getLocal();
|
||||||
// command writes new rev to DB and calls setRevision, which emits our signal
|
// command writes new rev to DB and calls setRevision, which emits our signal
|
||||||
DatabaseCommand_SetDynamicPlaylistRevision* cmd =
|
DatabaseCommand_SetDynamicPlaylistRevision* cmd =
|
||||||
new DatabaseCommand_SetDynamicPlaylistRevision( author,
|
new DatabaseCommand_SetDynamicPlaylistRevision( author,
|
||||||
guid(),
|
guid(),
|
||||||
newrev,
|
newrev,
|
||||||
oldrev,
|
oldrev,
|
||||||
orderedguids,
|
orderedguids,
|
||||||
added,
|
added,
|
||||||
entries,
|
entries,
|
||||||
type,
|
type,
|
||||||
Static,
|
Static,
|
||||||
controls );
|
controls );
|
||||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
|
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a new revision that will be an ondemand playlist, as it has no entries
|
// create a new revision that will be an ondemand playlist, as it has no entries
|
||||||
void
|
void
|
||||||
DynamicPlaylist::createNewRevision( const QString& newrev,
|
DynamicPlaylist::createNewRevision( const QString& newrev,
|
||||||
const QString& oldrev,
|
const QString& oldrev,
|
||||||
const QString& type,
|
const QString& type,
|
||||||
const QList< dyncontrol_ptr>& controls )
|
const QList< dyncontrol_ptr>& controls )
|
||||||
{
|
{
|
||||||
// can skip the entry stuff. just overwrite with new info
|
// can skip the entry stuff. just overwrite with new info
|
||||||
source_ptr author = SourceList::instance()->getLocal();
|
source_ptr author = SourceList::instance()->getLocal();
|
||||||
@@ -237,7 +237,7 @@ DynamicPlaylist::loadRevision( const QString& rev )
|
|||||||
bool ) ) );
|
bool ) ) );
|
||||||
|
|
||||||
}
|
}
|
||||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
|
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -257,8 +257,8 @@ DynamicPlaylist::reportCreated( const Tomahawk::dynplaylist_ptr& self )
|
|||||||
Q_ASSERT( !author().isNull() );
|
Q_ASSERT( !author().isNull() );
|
||||||
Q_ASSERT( !author()->collection().isNull() );
|
Q_ASSERT( !author()->collection().isNull() );
|
||||||
// will emit Collection::playlistCreated(...)
|
// will emit Collection::playlistCreated(...)
|
||||||
// qDebug() << "Creating dynplaylist belonging to:" << author().data() << author().isNull();
|
// qDebug() << "Creating dynplaylist belonging to:" << author().data() << author().isNull();
|
||||||
// qDebug() << "REPORTING DYNAMIC PLAYLIST CREATED:" << this << author()->friendlyName();
|
// qDebug() << "REPORTING DYNAMIC PLAYLIST CREATED:" << this << author()->friendlyName();
|
||||||
if( self->mode() == Static )
|
if( self->mode() == Static )
|
||||||
author()->collection()->addAutoPlaylist( self );
|
author()->collection()->addAutoPlaylist( self );
|
||||||
else
|
else
|
||||||
@@ -339,33 +339,33 @@ void DynamicPlaylist::setRevision( const QString& rev,
|
|||||||
setCurrentrevision( rev );
|
setCurrentrevision( rev );
|
||||||
}
|
}
|
||||||
// qDebug() << "EMITTING REVISION LOADED 1!";
|
// qDebug() << "EMITTING REVISION LOADED 1!";
|
||||||
emit dynamicRevisionLoaded( dpr );
|
emit dynamicRevisionLoaded( dpr );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DynamicPlaylist::setRevision( const QString& rev,
|
DynamicPlaylist::setRevision( const QString& rev,
|
||||||
const QList< QString >& neworderedguids,
|
const QList< QString >& neworderedguids,
|
||||||
const QList< QString >& oldorderedguids,
|
const QList< QString >& oldorderedguids,
|
||||||
const QString& type,
|
const QString& type,
|
||||||
const QList< QVariantMap>& controlsV,
|
const QList< QVariantMap>& controlsV,
|
||||||
bool is_newest_rev,
|
bool is_newest_rev,
|
||||||
const QMap< QString, Tomahawk::plentry_ptr >& addedmap,
|
const QMap< QString, Tomahawk::plentry_ptr >& addedmap,
|
||||||
bool applied )
|
bool applied )
|
||||||
{
|
{
|
||||||
if( QThread::currentThread() != thread() )
|
if( QThread::currentThread() != thread() )
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod( this,
|
QMetaObject::invokeMethod( this,
|
||||||
"setRevision",
|
"setRevision",
|
||||||
Qt::BlockingQueuedConnection,
|
Qt::BlockingQueuedConnection,
|
||||||
Q_ARG( QString, rev ),
|
Q_ARG( QString, rev ),
|
||||||
Q_ARG( QList<QString> , neworderedguids ),
|
Q_ARG( QList<QString> , neworderedguids ),
|
||||||
Q_ARG( QList<QString> , oldorderedguids ),
|
Q_ARG( QList<QString> , oldorderedguids ),
|
||||||
Q_ARG( QString , type ),
|
Q_ARG( QString , type ),
|
||||||
QGenericArgument( "QList< QVariantMap > " , (const void*)&controlsV ),
|
QGenericArgument( "QList< QVariantMap > " , (const void*)&controlsV ),
|
||||||
Q_ARG( bool, is_newest_rev ),
|
Q_ARG( bool, is_newest_rev ),
|
||||||
QGenericArgument( "QMap< QString,Tomahawk::plentry_ptr > " , (const void*)&addedmap ),
|
QGenericArgument( "QMap< QString,Tomahawk::plentry_ptr > " , (const void*)&addedmap ),
|
||||||
Q_ARG( bool, applied ) );
|
Q_ARG( bool, applied ) );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -416,10 +416,10 @@ void DynamicPlaylist::setRevision( const QString& rev,
|
|||||||
|
|
||||||
void
|
void
|
||||||
DynamicPlaylist::setRevision( const QString& rev,
|
DynamicPlaylist::setRevision( const QString& rev,
|
||||||
bool is_newest_rev,
|
bool is_newest_rev,
|
||||||
const QString& type,
|
const QString& type,
|
||||||
const QList< QVariantMap >& controlsV,
|
const QList< QVariantMap >& controlsV,
|
||||||
bool applied )
|
bool applied )
|
||||||
{
|
{
|
||||||
if( QThread::currentThread() != thread() )
|
if( QThread::currentThread() != thread() )
|
||||||
{
|
{
|
||||||
|
@@ -82,7 +82,8 @@ public:
|
|||||||
const QString& info,
|
const QString& info,
|
||||||
const QString& creator,
|
const QString& creator,
|
||||||
GeneratorMode mode,
|
GeneratorMode mode,
|
||||||
bool shared
|
bool shared,
|
||||||
|
const QString& type = QString()
|
||||||
);
|
);
|
||||||
static bool remove( const dynplaylist_ptr& playlist );
|
static bool remove( const dynplaylist_ptr& playlist );
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
@@ -55,6 +55,18 @@ SourceList::getLocal()
|
|||||||
return m_local;
|
return m_local;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SourceList::setWebSource( const source_ptr& websrc )
|
||||||
|
{
|
||||||
|
m_dummy = websrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
const
|
||||||
|
source_ptr SourceList::webSource() const
|
||||||
|
{
|
||||||
|
return m_dummy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SourceList::loadSources()
|
SourceList::loadSources()
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
@@ -40,6 +40,9 @@ public:
|
|||||||
const Tomahawk::source_ptr& getLocal();
|
const Tomahawk::source_ptr& getLocal();
|
||||||
void setLocal( const Tomahawk::source_ptr& localSrc );
|
void setLocal( const Tomahawk::source_ptr& localSrc );
|
||||||
|
|
||||||
|
void setWebSource( const Tomahawk::source_ptr& websrc );
|
||||||
|
const Tomahawk::source_ptr webSource() const;
|
||||||
|
|
||||||
void removeAllRemote();
|
void removeAllRemote();
|
||||||
|
|
||||||
QList<Tomahawk::source_ptr> sources( bool onlyOnline = false ) const;
|
QList<Tomahawk::source_ptr> sources( bool onlyOnline = false ) const;
|
||||||
@@ -57,7 +60,7 @@ signals:
|
|||||||
private slots:
|
private slots:
|
||||||
void setSources( const QList<Tomahawk::source_ptr>& sources );
|
void setSources( const QList<Tomahawk::source_ptr>& sources );
|
||||||
void sourceSynced();
|
void sourceSynced();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadSources();
|
void loadSources();
|
||||||
void add( const Tomahawk::source_ptr& source );
|
void add( const Tomahawk::source_ptr& source );
|
||||||
@@ -66,8 +69,9 @@ private:
|
|||||||
QMap< int, QString > m_sources_id2name;
|
QMap< int, QString > m_sources_id2name;
|
||||||
|
|
||||||
Tomahawk::source_ptr m_local;
|
Tomahawk::source_ptr m_local;
|
||||||
|
Tomahawk::source_ptr m_dummy;
|
||||||
mutable QMutex m_mut; // mutable so const methods can use a lock
|
mutable QMutex m_mut; // mutable so const methods can use a lock
|
||||||
|
|
||||||
static SourceList* s_instance;
|
static SourceList* s_instance;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -377,6 +377,18 @@ TomahawkSettings::appendRecentlyPlayedPlaylist( const Tomahawk::playlist_ptr& pl
|
|||||||
setValue( "playlists/recentlyPlayed", playlist_guids );
|
setValue( "playlists/recentlyPlayed", playlist_guids );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
TomahawkSettings::bookmarkPlaylist() const
|
||||||
|
{
|
||||||
|
return value( "playlists/bookmark", QString() ).toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TomahawkSettings::setBookmarkPlaylist( const QString& guid )
|
||||||
|
{
|
||||||
|
setValue( "playlists/bookmark", guid );
|
||||||
|
}
|
||||||
|
|
||||||
QStringList
|
QStringList
|
||||||
TomahawkSettings::sipPlugins() const
|
TomahawkSettings::sipPlugins() const
|
||||||
{
|
{
|
||||||
|
@@ -73,6 +73,9 @@ public:
|
|||||||
void setSipPlugins( const QStringList& plugins );
|
void setSipPlugins( const QStringList& plugins );
|
||||||
QStringList sipPlugins() const;
|
QStringList sipPlugins() const;
|
||||||
|
|
||||||
|
void setBookmarkPlaylist( const QString& guid );
|
||||||
|
QString bookmarkPlaylist() const;
|
||||||
|
|
||||||
// just the enabled sip plugins.
|
// just the enabled sip plugins.
|
||||||
void setEnabledSipPlugins( const QStringList& list );
|
void setEnabledSipPlugins( const QStringList& list );
|
||||||
QStringList enabledSipPlugins() const;
|
QStringList enabledSipPlugins() const;
|
||||||
|
@@ -29,6 +29,12 @@
|
|||||||
|
|
||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
|
void
|
||||||
|
XSPFLoader::setOverrideTitle( const QString& newTitle )
|
||||||
|
{
|
||||||
|
m_overrideTitle = newTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
XSPFLoader::load( const QUrl& url )
|
XSPFLoader::load( const QUrl& url )
|
||||||
@@ -116,13 +122,15 @@ XSPFLoader::gotBody()
|
|||||||
m_title = origTitle;
|
m_title = origTitle;
|
||||||
if ( m_title.isEmpty() )
|
if ( m_title.isEmpty() )
|
||||||
m_title = tr( "New Playlist" );
|
m_title = tr( "New Playlist" );
|
||||||
|
if( !m_overrideTitle.isEmpty() )
|
||||||
|
m_title = m_overrideTitle;
|
||||||
|
|
||||||
bool shownError = false;
|
bool shownError = false;
|
||||||
for ( unsigned int i = 0; i < tracklist.length(); i++ )
|
for ( unsigned int i = 0; i < tracklist.length(); i++ )
|
||||||
{
|
{
|
||||||
QDomNode e = tracklist.at( i );
|
QDomNode e = tracklist.at( i );
|
||||||
|
|
||||||
QString artist, album, track, duration, annotation;
|
QString artist, album, track, duration, annotation, url;
|
||||||
QDomElement n = e.firstChildElement();
|
QDomElement n = e.firstChildElement();
|
||||||
for ( ; !n.isNull(); n = n.nextSiblingElement() ) {
|
for ( ; !n.isNull(); n = n.nextSiblingElement() ) {
|
||||||
if (n.namespaceURI() == m_NS && n.localName() == "duration") {
|
if (n.namespaceURI() == m_NS && n.localName() == "duration") {
|
||||||
@@ -135,6 +143,8 @@ XSPFLoader::gotBody()
|
|||||||
album = n.text();
|
album = n.text();
|
||||||
} else if (n.namespaceURI() == m_NS && n.localName() == "title") {
|
} else if (n.namespaceURI() == m_NS && n.localName() == "title") {
|
||||||
track = n.text();
|
track = n.text();
|
||||||
|
} else if (n.namespaceURI() == m_NS && n.localName() == "url") {
|
||||||
|
url = n.text();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,6 +164,8 @@ XSPFLoader::gotBody()
|
|||||||
|
|
||||||
p->setQuery( Tomahawk::Query::get( artist, track, album, uuid() ) );
|
p->setQuery( Tomahawk::Query::get( artist, track, album, uuid() ) );
|
||||||
p->query()->setDuration( duration.toInt() / 1000 );
|
p->query()->setDuration( duration.toInt() / 1000 );
|
||||||
|
if( !url.isEmpty() )
|
||||||
|
p->query()->setResultHint( url );
|
||||||
m_entries << p;
|
m_entries << p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -53,6 +53,7 @@ public:
|
|||||||
|
|
||||||
QList< Tomahawk::plentry_ptr > entries() const { return m_entries; }
|
QList< Tomahawk::plentry_ptr > entries() const { return m_entries; }
|
||||||
|
|
||||||
|
void setOverrideTitle( const QString& newTitle );
|
||||||
signals:
|
signals:
|
||||||
void failed();
|
void failed();
|
||||||
void ok( const Tomahawk::playlist_ptr& );
|
void ok( const Tomahawk::playlist_ptr& );
|
||||||
@@ -70,7 +71,7 @@ private:
|
|||||||
void gotBody();
|
void gotBody();
|
||||||
|
|
||||||
bool m_autoCreate;
|
bool m_autoCreate;
|
||||||
QString m_NS;
|
QString m_NS,m_overrideTitle;
|
||||||
QList< Tomahawk::plentry_ptr > m_entries;
|
QList< Tomahawk::plentry_ptr > m_entries;
|
||||||
QString m_title, m_info, m_creator;
|
QString m_title, m_info, m_creator;
|
||||||
|
|
||||||
|
@@ -149,6 +149,22 @@ ViewManager::queue() const
|
|||||||
return m_queueView->queue();
|
return m_queueView->queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PlaylistView*
|
||||||
|
ViewManager::createPageForPlaylist( const playlist_ptr& pl )
|
||||||
|
{
|
||||||
|
PlaylistView* view = new PlaylistView();
|
||||||
|
|
||||||
|
PlaylistModel* model = new PlaylistModel();
|
||||||
|
view->setPlaylistModel( model );
|
||||||
|
view->setFrameShape( QFrame::NoFrame );
|
||||||
|
view->setAttribute( Qt::WA_MacShowFocusRect, 0 );
|
||||||
|
model->loadPlaylist( pl );
|
||||||
|
pl->resolve();
|
||||||
|
|
||||||
|
m_playlistViews.insert( pl, view );
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Tomahawk::ViewPage*
|
Tomahawk::ViewPage*
|
||||||
ViewManager::show( const Tomahawk::playlist_ptr& playlist )
|
ViewManager::show( const Tomahawk::playlist_ptr& playlist )
|
||||||
@@ -156,15 +172,7 @@ ViewManager::show( const Tomahawk::playlist_ptr& playlist )
|
|||||||
PlaylistView* view;
|
PlaylistView* view;
|
||||||
if ( !m_playlistViews.contains( playlist ) )
|
if ( !m_playlistViews.contains( playlist ) )
|
||||||
{
|
{
|
||||||
view = new PlaylistView();
|
view = createPageForPlaylist( playlist );
|
||||||
PlaylistModel* model = new PlaylistModel();
|
|
||||||
view->setPlaylistModel( model );
|
|
||||||
view->setFrameShape( QFrame::NoFrame );
|
|
||||||
view->setAttribute( Qt::WA_MacShowFocusRect, 0 );
|
|
||||||
model->loadPlaylist( playlist );
|
|
||||||
playlist->resolve();
|
|
||||||
|
|
||||||
m_playlistViews.insert( playlist, view );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -67,6 +67,7 @@ public:
|
|||||||
|
|
||||||
QWidget* widget() const { return m_widget; }
|
QWidget* widget() const { return m_widget; }
|
||||||
PlaylistView* queue() const;
|
PlaylistView* queue() const;
|
||||||
|
TopBar* topbar() const { return m_topbar; }
|
||||||
|
|
||||||
bool isSuperCollectionVisible() const;
|
bool isSuperCollectionVisible() const;
|
||||||
bool isNewPlaylistPageVisible() const;
|
bool isNewPlaylistPageVisible() const;
|
||||||
@@ -76,14 +77,6 @@ public:
|
|||||||
Tomahawk::ViewPage* pageForInterface( PlaylistInterface* interface ) const;
|
Tomahawk::ViewPage* pageForInterface( PlaylistInterface* interface ) const;
|
||||||
int positionInHistory( Tomahawk::ViewPage* page ) const;
|
int positionInHistory( Tomahawk::ViewPage* page ) const;
|
||||||
|
|
||||||
// Returns the shown viewpage
|
|
||||||
Tomahawk::ViewPage* show( const Tomahawk::playlist_ptr& playlist );
|
|
||||||
Tomahawk::ViewPage* show( const Tomahawk::dynplaylist_ptr& playlist );
|
|
||||||
Tomahawk::ViewPage* show( const Tomahawk::artist_ptr& artist );
|
|
||||||
Tomahawk::ViewPage* show( const Tomahawk::album_ptr& album );
|
|
||||||
Tomahawk::ViewPage* show( const Tomahawk::collection_ptr& collection );
|
|
||||||
Tomahawk::ViewPage* show( const Tomahawk::source_ptr& source );
|
|
||||||
|
|
||||||
Tomahawk::ViewPage* show( Tomahawk::ViewPage* page );
|
Tomahawk::ViewPage* show( Tomahawk::ViewPage* page );
|
||||||
|
|
||||||
Tomahawk::ViewPage* welcomeWidget() const { return m_welcomeWidget; }
|
Tomahawk::ViewPage* welcomeWidget() const { return m_welcomeWidget; }
|
||||||
@@ -94,6 +87,9 @@ public:
|
|||||||
Tomahawk::ViewPage* pageForDynPlaylist( const Tomahawk::dynplaylist_ptr& pl ) const;
|
Tomahawk::ViewPage* pageForDynPlaylist( const Tomahawk::dynplaylist_ptr& pl ) const;
|
||||||
Tomahawk::ViewPage* pageForCollection( const Tomahawk::collection_ptr& pl ) const;
|
Tomahawk::ViewPage* pageForCollection( const Tomahawk::collection_ptr& pl ) const;
|
||||||
|
|
||||||
|
// only use this is you need to create a playlist and show it directly and want it to be
|
||||||
|
// linked to the sidebar. call it right after creating the playlist
|
||||||
|
PlaylistView* createPageForPlaylist( const Tomahawk::playlist_ptr& pl );
|
||||||
signals:
|
signals:
|
||||||
void numSourcesChanged( unsigned int sources );
|
void numSourcesChanged( unsigned int sources );
|
||||||
void numTracksChanged( unsigned int tracks );
|
void numTracksChanged( unsigned int tracks );
|
||||||
@@ -127,6 +123,14 @@ public slots:
|
|||||||
Tomahawk::ViewPage* showWelcomePage();
|
Tomahawk::ViewPage* showWelcomePage();
|
||||||
void showCurrentTrack();
|
void showCurrentTrack();
|
||||||
|
|
||||||
|
// Returns the shown viewpage
|
||||||
|
Tomahawk::ViewPage* show( const Tomahawk::playlist_ptr& playlist );
|
||||||
|
Tomahawk::ViewPage* show( const Tomahawk::dynplaylist_ptr& playlist );
|
||||||
|
Tomahawk::ViewPage* show( const Tomahawk::artist_ptr& artist );
|
||||||
|
Tomahawk::ViewPage* show( const Tomahawk::album_ptr& album );
|
||||||
|
Tomahawk::ViewPage* show( const Tomahawk::collection_ptr& collection );
|
||||||
|
Tomahawk::ViewPage* show( const Tomahawk::source_ptr& source );
|
||||||
|
|
||||||
void historyBack();
|
void historyBack();
|
||||||
void historyForward();
|
void historyForward();
|
||||||
void showHistory( int historyPosition );
|
void showHistory( int historyPosition );
|
||||||
|
32
src/libtomahawk/webcollection.cpp
Normal file
32
src/libtomahawk/webcollection.cpp
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2011 Leo Franchi <lfranchi@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.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "webcollection.h"
|
||||||
|
|
||||||
|
using namespace Tomahawk;
|
||||||
|
|
||||||
|
WebCollection::WebCollection( const source_ptr& source, const QString& name, QObject* parent )
|
||||||
|
: Collection( source, name, parent )
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
WebCollection::~WebCollection()
|
||||||
|
{
|
||||||
|
}
|
43
src/libtomahawk/webcollection.h
Normal file
43
src/libtomahawk/webcollection.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
Copyright (C) 2011 Leo Franchi <lfranchi@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.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef WEBCOLLECTION_H
|
||||||
|
#define WEBCOLLECTION_H
|
||||||
|
|
||||||
|
#include "collection.h"
|
||||||
|
#include "dllmacro.h"
|
||||||
|
|
||||||
|
namespace Tomahawk
|
||||||
|
{
|
||||||
|
|
||||||
|
class DLLEXPORT WebCollection : public Collection
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
WebCollection( const source_ptr& source, const QString& name = QString(), QObject* parent = 0 );
|
||||||
|
virtual ~WebCollection();
|
||||||
|
|
||||||
|
virtual void removeTracks( const QDir& ) {}
|
||||||
|
virtual void addTracks( const QList< QVariant >& ) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WEBCOLLECTION_H
|
@@ -80,9 +80,9 @@ Scrobbler::trackStarted( const Tomahawk::result_ptr& track )
|
|||||||
trackInfo["artist"] = track->artist()->name();
|
trackInfo["artist"] = track->artist()->name();
|
||||||
trackInfo["album"] = track->album()->name();
|
trackInfo["album"] = track->album()->name();
|
||||||
trackInfo["duration"] = QString::number( track->duration() );
|
trackInfo["duration"] = QString::number( track->duration() );
|
||||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo(
|
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||||
s_scInfoIdentifier, Tomahawk::InfoSystem::InfoMiscSubmitNowPlaying,
|
s_scInfoIdentifier, Tomahawk::InfoSystem::InfoSubmitNowPlaying,
|
||||||
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() );
|
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ) );
|
||||||
|
|
||||||
m_scrobblePoint = ScrobblePoint( track->duration() / 2 );
|
m_scrobblePoint = ScrobblePoint( track->duration() / 2 );
|
||||||
}
|
}
|
||||||
@@ -128,9 +128,9 @@ Scrobbler::scrobble()
|
|||||||
{
|
{
|
||||||
Q_ASSERT( QThread::currentThread() == thread() );
|
Q_ASSERT( QThread::currentThread() == thread() );
|
||||||
|
|
||||||
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo(
|
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
|
||||||
s_scInfoIdentifier, Tomahawk::InfoSystem::InfoMiscSubmitScrobble,
|
s_scInfoIdentifier, Tomahawk::InfoSystem::InfoSubmitScrobble,
|
||||||
QVariant(), Tomahawk::InfoSystem::InfoCustomData() );
|
QVariant() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -141,13 +141,7 @@ Scrobbler::infoSystemInfo( QString caller, Tomahawk::InfoSystem::InfoType type,
|
|||||||
Q_UNUSED( output );
|
Q_UNUSED( output );
|
||||||
Q_UNUSED( customData );
|
Q_UNUSED( customData );
|
||||||
if ( caller == s_scInfoIdentifier )
|
if ( caller == s_scInfoIdentifier )
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
qDebug() << Q_FUNC_INFO;
|
||||||
if ( type == Tomahawk::InfoSystem::InfoMiscSubmitNowPlaying )
|
|
||||||
qDebug() << "Scrobbler received now playing response from InfoSystem";
|
|
||||||
else if ( type == Tomahawk::InfoSystem::InfoMiscSubmitScrobble )
|
|
||||||
qDebug() << "Scrobbler received scrobble response from InfoSystem";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -8,7 +8,6 @@ add_definitions( -DSIPDLLEXPORT_PRO )
|
|||||||
|
|
||||||
set( jabberSources
|
set( jabberSources
|
||||||
jabber.cpp
|
jabber.cpp
|
||||||
jabber_p.cpp
|
|
||||||
tomahawksipmessage.cpp
|
tomahawksipmessage.cpp
|
||||||
tomahawksipmessagefactory.cpp
|
tomahawksipmessagefactory.cpp
|
||||||
avatarmanager.cpp
|
avatarmanager.cpp
|
||||||
@@ -16,7 +15,6 @@ set( jabberSources
|
|||||||
|
|
||||||
set( jabberHeaders
|
set( jabberHeaders
|
||||||
jabber.h
|
jabber.h
|
||||||
jabber_p.h
|
|
||||||
tomahawksipmessage.h
|
tomahawksipmessage.h
|
||||||
tomahawksipmessagefactory.h
|
tomahawksipmessagefactory.h
|
||||||
avatarmanager.h
|
avatarmanager.h
|
||||||
|
@@ -10,7 +10,6 @@ set( googleHeaders
|
|||||||
|
|
||||||
set( googleSources
|
set( googleSources
|
||||||
../jabber.cpp
|
../jabber.cpp
|
||||||
../jabber_p.cpp
|
|
||||||
../tomahawksipmessage.cpp
|
../tomahawksipmessage.cpp
|
||||||
../tomahawksipmessagefactory.cpp
|
../tomahawksipmessagefactory.cpp
|
||||||
../avatarmanager.cpp
|
../avatarmanager.cpp
|
||||||
|
@@ -19,13 +19,27 @@
|
|||||||
|
|
||||||
#include "jabber.h"
|
#include "jabber.h"
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#include "tomahawksettings.h"
|
#include "tomahawksettings.h"
|
||||||
|
#include "tomahawksipmessage.h"
|
||||||
|
#include "tomahawksipmessagefactory.h"
|
||||||
|
|
||||||
|
#include <jreen/jid.h>
|
||||||
|
#include <jreen/capabilities.h>
|
||||||
|
#include <jreen/vcardupdate.h>
|
||||||
|
#include <jreen/vcard.h>
|
||||||
|
|
||||||
|
#include <qjson/parser.h>
|
||||||
|
#include <qjson/serializer.h>
|
||||||
|
|
||||||
#include <QtPlugin>
|
#include <QtPlugin>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QLineEdit>
|
#include <QLineEdit>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#include "ui_configwidget.h"
|
#include "ui_configwidget.h"
|
||||||
|
|
||||||
@@ -41,14 +55,16 @@ JabberFactory::icon() const
|
|||||||
return QIcon( ":/jabber-icon.png" );
|
return QIcon( ":/jabber-icon.png" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
JabberPlugin::JabberPlugin( const QString& pluginId )
|
JabberPlugin::JabberPlugin( const QString& pluginId )
|
||||||
: SipPlugin( pluginId )
|
: SipPlugin( pluginId )
|
||||||
, p( 0 )
|
|
||||||
, m_menu( 0 )
|
, m_menu( 0 )
|
||||||
, m_addFriendAction( 0 )
|
, m_addFriendAction( 0 )
|
||||||
, m_state( Disconnected )
|
, m_state( Disconnected )
|
||||||
{
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
|
qsrand(QDateTime::currentDateTime().toTime_t());
|
||||||
|
|
||||||
m_configWidget = QWeakPointer< QWidget >( new QWidget );
|
m_configWidget = QWeakPointer< QWidget >( new QWidget );
|
||||||
m_ui = new Ui_JabberConfig;
|
m_ui = new Ui_JabberConfig;
|
||||||
m_ui->setupUi( m_configWidget.data() );
|
m_ui->setupUi( m_configWidget.data() );
|
||||||
@@ -60,17 +76,56 @@ JabberPlugin::JabberPlugin( const QString& pluginId )
|
|||||||
m_ui->jabberServer->setText( readServer() );
|
m_ui->jabberServer->setText( readServer() );
|
||||||
m_ui->jabberPort->setValue( readPort() );
|
m_ui->jabberPort->setValue( readPort() );
|
||||||
|
|
||||||
|
// setup JID object
|
||||||
|
Jreen::JID jid = Jreen::JID( accountName() );
|
||||||
|
|
||||||
|
// general client setup
|
||||||
|
m_client = new Jreen::Client( jid, m_currentPassword );
|
||||||
|
m_client->registerStanzaExtension(new TomahawkSipMessageFactory);
|
||||||
|
m_currentResource = QString::fromAscii( "tomahawk%1" ).arg( QString::number( qrand() % 10000 ) );
|
||||||
|
m_client->setResource( m_currentResource );
|
||||||
|
|
||||||
|
// add VCardUpdate extension to own presence
|
||||||
|
m_client->presence().addExtension( new Jreen::VCardUpdate() );
|
||||||
|
|
||||||
|
// initialize the AvatarManager
|
||||||
|
m_avatarManager = new AvatarManager( m_client );
|
||||||
|
|
||||||
|
// setup disco
|
||||||
|
m_client->disco()->setSoftwareVersion( "Tomahawk Player", TOMAHAWK_VERSION, CMAKE_SYSTEM );
|
||||||
|
m_client->disco()->addIdentity( Jreen::Disco::Identity( "client", "type", "tomahawk", "en" ) );
|
||||||
|
m_client->disco()->addFeature( TOMAHAWK_FEATURE );
|
||||||
|
|
||||||
|
// setup caps node, legacy peer detection - used before 0.1
|
||||||
|
Jreen::Capabilities::Ptr caps = m_client->presence().findExtension<Jreen::Capabilities>();
|
||||||
|
caps->setNode( TOMAHAWK_CAP_NODE_NAME );
|
||||||
|
//FIXME: caps->setVersion( TOMAHAWK_VERSION );
|
||||||
|
|
||||||
|
// print connection parameters
|
||||||
|
qDebug() << "Our JID set to:" << m_client->jid().full();
|
||||||
|
qDebug() << "Our Server set to:" << m_client->server();
|
||||||
|
qDebug() << "Our Port set to" << m_client->port();
|
||||||
|
|
||||||
|
// setup slots
|
||||||
|
connect(m_client->connection(), SIGNAL(error(SocketError)), SLOT(onError(SocketError)));
|
||||||
|
connect(m_client, SIGNAL(serverFeaturesReceived(QSet<QString>)), SLOT(onConnect()));
|
||||||
|
connect(m_client, SIGNAL(disconnected(Jreen::Client::DisconnectReason)), SLOT(onDisconnect(Jreen::Client::DisconnectReason)));
|
||||||
|
connect(m_client, SIGNAL(newMessage(Jreen::Message)), SLOT(onNewMessage(Jreen::Message)));
|
||||||
|
connect(m_client, SIGNAL(newPresence(Jreen::Presence)), SLOT(onNewPresence(Jreen::Presence)));
|
||||||
|
connect(m_client, SIGNAL(newIQ(Jreen::IQ)), SLOT(onNewIq(Jreen::IQ)));
|
||||||
|
|
||||||
|
connect(m_avatarManager, SIGNAL(newAvatar(QString)), SLOT(onNewAvatar(QString)));
|
||||||
}
|
}
|
||||||
|
|
||||||
JabberPlugin::~JabberPlugin()
|
JabberPlugin::~JabberPlugin()
|
||||||
{
|
{
|
||||||
delete p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
JabberPlugin::setProxy( QNetworkProxy* proxy )
|
JabberPlugin::setProxy( QNetworkProxy* proxy )
|
||||||
{
|
{
|
||||||
p->setProxy( proxy );
|
qDebug() << Q_FUNC_INFO << "Not implemented";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -124,32 +179,13 @@ JabberPlugin::connectPlugin( bool startup )
|
|||||||
QString password = m_currentPassword = readPassword();
|
QString password = m_currentPassword = readPassword();
|
||||||
unsigned int port = m_currentPort = readPort();
|
unsigned int port = m_currentPort = readPort();
|
||||||
|
|
||||||
QStringList splitJid = jid.split( '@', QString::SkipEmptyParts );
|
qDebug() << "Connecting to the XMPP server..." << (m_state == Connected);
|
||||||
if ( splitJid.size() < 2 )
|
qDebug() << m_client->jid().full();
|
||||||
{
|
//m_client->setServer( m_client->jid().domain() );
|
||||||
qDebug() << "JID did not have an @ in it, could not find a server part";
|
qDebug() << m_client->server() << m_client->port();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( port < 1 || port > 65535 || jid.isEmpty() || password.isEmpty() )
|
QTimer::singleShot(1000, m_client, SLOT( connectToServer() ) );
|
||||||
{
|
//m_client->connectToServer();
|
||||||
qDebug() << "Jabber credentials look wrong, not connecting";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete p;
|
|
||||||
p = new Jabber_p( jid, password, ( server.isEmpty() ? QString() : server ), port );
|
|
||||||
|
|
||||||
QObject::connect( p, SIGNAL( peerOnline( QString ) ), SIGNAL( peerOnline( QString ) ) );
|
|
||||||
QObject::connect( p, SIGNAL( peerOffline( QString ) ), SIGNAL( peerOffline( QString ) ) );
|
|
||||||
QObject::connect( p, SIGNAL( msgReceived( QString, QString ) ), SIGNAL( msgReceived( QString, QString ) ) );
|
|
||||||
|
|
||||||
QObject::connect( p, SIGNAL( connected() ), SLOT( onConnected() ) );
|
|
||||||
QObject::connect( p, SIGNAL( disconnected() ), SLOT( onDisconnected() ) );
|
|
||||||
|
|
||||||
QObject::connect( p, SIGNAL( authError( int, QString ) ), SLOT( onAuthError( int, QString ) ) );
|
|
||||||
QObject::connect( p, SIGNAL( avatarReceived( QString, QPixmap ) ), SIGNAL( avatarReceived( QString, QPixmap ) ) );
|
|
||||||
QObject::connect( p, SIGNAL( avatarReceived( QPixmap ) ), SIGNAL( avatarReceived( QPixmap) ) );
|
|
||||||
|
|
||||||
m_state = Connecting;
|
m_state = Connecting;
|
||||||
emit stateChanged( m_state );
|
emit stateChanged( m_state );
|
||||||
@@ -159,58 +195,131 @@ JabberPlugin::connectPlugin( bool startup )
|
|||||||
void
|
void
|
||||||
JabberPlugin::disconnectPlugin()
|
JabberPlugin::disconnectPlugin()
|
||||||
{
|
{
|
||||||
onDisconnected();
|
qDebug() << Q_FUNC_INFO << (m_state == Connected);
|
||||||
|
|
||||||
if ( p )
|
if( m_state == Disconnected )
|
||||||
p->disconnect();
|
return;
|
||||||
|
|
||||||
delete p;
|
foreach(const Jreen::JID &peer, m_peers.keys())
|
||||||
p = 0;
|
{
|
||||||
|
handlePeerStatus(peer, Jreen::Presence::Unavailable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//m_roster->deleteLater();
|
||||||
|
//m_roster = 0;
|
||||||
|
//m_room->deleteLater();
|
||||||
|
//m_room = 0;
|
||||||
|
|
||||||
|
m_peers.clear();
|
||||||
|
m_legacy_peers.clear();
|
||||||
|
|
||||||
|
m_client->disconnectFromServer(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
JabberPlugin::onConnected()
|
JabberPlugin::onConnect()
|
||||||
{
|
{
|
||||||
if( !m_menu ) {
|
qDebug() << Q_FUNC_INFO;
|
||||||
m_menu = new QMenu( QString( "JREEN (" ).append( accountName() ).append(")" ) );
|
|
||||||
m_addFriendAction = m_menu->addAction( "Add Friend..." );
|
|
||||||
QAction *connectAction = m_menu->addAction( "Connect" );
|
|
||||||
|
|
||||||
connect( m_addFriendAction, SIGNAL(triggered() ),
|
// update jid resource, servers like gtalk use resource binding and may
|
||||||
this, SLOT( showAddFriendDialog() ) );
|
// have changed our requested /resource
|
||||||
connect( connectAction, SIGNAL( triggered() ), SLOT( connectPlugin() ) );
|
if ( m_client->jid().resource() != m_currentResource )
|
||||||
|
{
|
||||||
emit addMenu( m_menu );
|
m_currentResource = m_client->jid().resource();
|
||||||
|
emit jidChanged( m_client->jid().full() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qDebug() << "Connected as:" << m_client->jid().full();
|
||||||
|
|
||||||
|
// set presence to least valid value
|
||||||
|
m_client->setPresence(Jreen::Presence::XA, "Got Tomahawk? http://gettomahawk.com", -127);
|
||||||
|
|
||||||
|
// set ping timeout to 15 secs (TODO: verify if this works)
|
||||||
|
m_client->setPingInterval(1000);
|
||||||
|
|
||||||
|
// load roster
|
||||||
|
m_roster = new Jreen::SimpleRoster( m_client );
|
||||||
|
m_roster->load();
|
||||||
|
|
||||||
|
//FIXME: this implementation is totally broken atm, so it's disabled to avoid harm :P
|
||||||
|
// join MUC with bare jid as nickname
|
||||||
|
//TODO: make the room a list of rooms and make that configurable
|
||||||
|
QString mucNickname = QString( "tomahawk@conference.qutim.org/" ).append( QString( m_client->jid().bare() ).replace( "@", "-" ) );
|
||||||
|
//m_room = new Jreen::MUCRoom(m_client, Jreen::JID( mucNickname ) );
|
||||||
|
//m_room->setHistorySeconds(0);
|
||||||
|
//m_room->join();
|
||||||
|
|
||||||
|
// treat muc participiants like contacts
|
||||||
|
//connect( m_room, SIGNAL( messageReceived( Jreen::Message, bool ) ), this, SLOT( onNewMessage( Jreen::Message ) ) );
|
||||||
|
//connect( m_room, SIGNAL( presenceReceived( Jreen::Presence, const Jreen::MUCRoom::Participant* ) ), this, SLOT( onNewPresence( Jreen::Presence ) ) );
|
||||||
|
|
||||||
m_state = Connected;
|
m_state = Connected;
|
||||||
|
|
||||||
emit stateChanged( m_state );
|
emit stateChanged( m_state );
|
||||||
|
|
||||||
|
addMenuHelper();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
JabberPlugin::onDisconnected()
|
JabberPlugin::onDisconnect( Jreen::Client::DisconnectReason reason )
|
||||||
{
|
{
|
||||||
if( m_menu && m_addFriendAction ) {
|
qDebug() << Q_FUNC_INFO;
|
||||||
emit removeMenu( m_menu );
|
|
||||||
|
|
||||||
delete m_menu;
|
QString errorMessage;
|
||||||
m_menu = 0;
|
bool reconnect = false;
|
||||||
m_addFriendAction = 0; // deleted by menu
|
int reconnectInSeconds = 0;
|
||||||
|
|
||||||
|
switch( reason )
|
||||||
|
{
|
||||||
|
case Jreen::Client::User:
|
||||||
|
errorMessage = "User Interaction";
|
||||||
|
break;
|
||||||
|
case Jreen::Client::HostUnknown:
|
||||||
|
errorMessage = "Host is unknown";
|
||||||
|
break;
|
||||||
|
case Jreen::Client::ItemNotFound:
|
||||||
|
errorMessage = "Item not found";
|
||||||
|
break;
|
||||||
|
case Jreen::Client::AuthorizationError:
|
||||||
|
errorMessage = "Authorization Error";
|
||||||
|
break;
|
||||||
|
case Jreen::Client::RemoteStreamError:
|
||||||
|
errorMessage = "Remote Stream Error";
|
||||||
|
reconnect = true;
|
||||||
|
break;
|
||||||
|
case Jreen::Client::RemoteConnectionFailed:
|
||||||
|
errorMessage = "Remote Connection failed";
|
||||||
|
break;
|
||||||
|
case Jreen::Client::InternalServerError:
|
||||||
|
errorMessage = "Internal Server Error";
|
||||||
|
reconnect = true;
|
||||||
|
break;
|
||||||
|
case Jreen::Client::SystemShutdown:
|
||||||
|
errorMessage = "System shutdown";
|
||||||
|
reconnect = true;
|
||||||
|
reconnectInSeconds = 60;
|
||||||
|
break;
|
||||||
|
case Jreen::Client::Conflict:
|
||||||
|
errorMessage = "Conflict";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Jreen::Client::Unknown:
|
||||||
|
errorMessage = "Unknown";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
qDebug() << "Not all Client::DisconnectReasons checked";
|
||||||
|
Q_ASSERT(false);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_state = Disconnected;
|
switch( reason )
|
||||||
|
|
||||||
emit stateChanged( m_state );
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
JabberPlugin::onAuthError( int code, const QString& msg )
|
|
||||||
{
|
|
||||||
switch( code )
|
|
||||||
{
|
{
|
||||||
|
case Jreen::Client::User:
|
||||||
|
break;
|
||||||
|
|
||||||
case Jreen::Client::AuthorizationError:
|
case Jreen::Client::AuthorizationError:
|
||||||
emit error( SipPlugin::AuthError, msg );
|
emit error( SipPlugin::AuthError, errorMessage );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Jreen::Client::HostUnknown:
|
case Jreen::Client::HostUnknown:
|
||||||
@@ -221,7 +330,7 @@ JabberPlugin::onAuthError( int code, const QString& msg )
|
|||||||
case Jreen::Client::SystemShutdown:
|
case Jreen::Client::SystemShutdown:
|
||||||
case Jreen::Client::Conflict:
|
case Jreen::Client::Conflict:
|
||||||
case Jreen::Client::Unknown:
|
case Jreen::Client::Unknown:
|
||||||
emit error( SipPlugin::ConnectionError, msg );
|
emit error( SipPlugin::ConnectionError, errorMessage );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -230,29 +339,97 @@ JabberPlugin::onAuthError( int code, const QString& msg )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_state = Disconnected;
|
m_state = Disconnected;
|
||||||
|
|
||||||
emit stateChanged( m_state );
|
emit stateChanged( m_state );
|
||||||
|
|
||||||
|
removeMenuHelper();
|
||||||
|
|
||||||
|
if(reconnect)
|
||||||
|
QTimer::singleShot(reconnectInSeconds*1000, this, SLOT(connectPlugin()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
JabberPlugin::onAuthError( int code, const QString& msg )
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
JabberPlugin::sendMsg(const QString& to, const QString& msg)
|
JabberPlugin::sendMsg(const QString& to, const QString& msg)
|
||||||
{
|
{
|
||||||
if ( p )
|
qDebug() << Q_FUNC_INFO << to << msg;
|
||||||
p->sendMsg( to, msg );
|
|
||||||
|
if ( !m_client ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_legacy_peers.contains( to ) )
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO << to << "Send legacy message" << msg;
|
||||||
|
Jreen::Message m( Jreen::Message::Chat, Jreen::JID(to), msg);
|
||||||
|
m_client->send( m );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************************************************
|
||||||
|
* Obsolete this by a SipMessage class
|
||||||
|
*/
|
||||||
|
QJson::Parser parser;
|
||||||
|
bool ok;
|
||||||
|
QVariant v = parser.parse( msg.toAscii(), &ok );
|
||||||
|
if ( !ok || v.type() != QVariant::Map )
|
||||||
|
{
|
||||||
|
qDebug() << "Invalid JSON in XMPP msg";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QVariantMap m = v.toMap();
|
||||||
|
/*******************************************************/
|
||||||
|
|
||||||
|
TomahawkSipMessage *sipMessage;
|
||||||
|
if(m["visible"].toBool())
|
||||||
|
{
|
||||||
|
sipMessage = new TomahawkSipMessage(m["ip"].toString(),
|
||||||
|
m["port"].toInt(),
|
||||||
|
m["uniqname"].toString(),
|
||||||
|
m["key"].toString(),
|
||||||
|
m["visible"].toBool()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sipMessage = new TomahawkSipMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
qDebug() << "Send sip messsage to " << to;
|
||||||
|
Jreen::IQ iq( Jreen::IQ::Set, to );
|
||||||
|
iq.addExtension( sipMessage );
|
||||||
|
|
||||||
|
m_client->send( iq, this, SLOT( onNewIq( Jreen::IQ, int ) ), SipMessageSent );
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
JabberPlugin::broadcastMsg(const QString& msg)
|
JabberPlugin::broadcastMsg(const QString& msg)
|
||||||
{
|
{
|
||||||
if ( p )
|
qDebug() << Q_FUNC_INFO;
|
||||||
p->broadcastMsg( msg );
|
|
||||||
|
if ( !m_client )
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach( const Jreen::JID& jid, m_peers.keys() )
|
||||||
|
{
|
||||||
|
sendMsg( jid.full(), msg );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
JabberPlugin::addContact(const QString& jid, const QString& msg)
|
JabberPlugin::addContact(const QString& jid, const QString& msg)
|
||||||
{
|
{
|
||||||
if ( p )
|
// Add contact to the Tomahawk group on the roster
|
||||||
p->addContact( jid, msg );
|
m_roster->subscribe( jid, msg, jid, QStringList() << "Tomahawk" );
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -287,13 +464,299 @@ JabberPlugin::checkSettings()
|
|||||||
m_currentServer = readServer();
|
m_currentServer = readServer();
|
||||||
m_currentPort = readPort();
|
m_currentPort = readPort();
|
||||||
|
|
||||||
if ( reconnect && ( p || readAutoConnect() ) )
|
if ( reconnect )
|
||||||
{
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO << "Reconnecting jreen plugin...";
|
||||||
disconnectPlugin();
|
disconnectPlugin();
|
||||||
|
|
||||||
|
m_currentUsername = accountName();
|
||||||
|
m_currentPassword = readPassword();
|
||||||
|
m_currentServer = readServer();
|
||||||
|
m_currentPort = readPort();
|
||||||
|
|
||||||
|
Jreen::JID jid = Jreen::JID( accountName() );
|
||||||
|
m_client->setJID( jid );
|
||||||
|
m_client->setPassword( m_currentPassword );
|
||||||
|
m_client->setServer( m_currentServer );
|
||||||
|
m_client->setPort( m_currentPort );
|
||||||
|
|
||||||
|
qDebug() << Q_FUNC_INFO << "Updated settings";
|
||||||
connectPlugin( false );
|
connectPlugin( false );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JabberPlugin::addMenuHelper()
|
||||||
|
{
|
||||||
|
if( !m_menu )
|
||||||
|
{
|
||||||
|
m_menu = new QMenu( QString( "JREEN (" ).append( accountName() ).append(")" ) );
|
||||||
|
m_addFriendAction = m_menu->addAction( "Add Friend..." );
|
||||||
|
|
||||||
|
connect( m_addFriendAction, SIGNAL( triggered() ), this, SLOT( showAddFriendDialog() ) );
|
||||||
|
|
||||||
|
emit addMenu( m_menu );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JabberPlugin::removeMenuHelper()
|
||||||
|
{
|
||||||
|
if( m_menu && m_addFriendAction )
|
||||||
|
{
|
||||||
|
emit removeMenu( m_menu );
|
||||||
|
|
||||||
|
delete m_menu;
|
||||||
|
m_menu = 0;
|
||||||
|
m_addFriendAction = 0; // deleted by menu
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JabberPlugin::onNewMessage(const Jreen::Message& message)
|
||||||
|
{
|
||||||
|
QString from = message.from().full();
|
||||||
|
QString msg = message.body();
|
||||||
|
|
||||||
|
if ( msg.isEmpty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
QJson::Parser parser;
|
||||||
|
bool ok;
|
||||||
|
QVariant v = parser.parse( msg.toAscii(), &ok );
|
||||||
|
if ( !ok || v.type() != QVariant::Map )
|
||||||
|
{
|
||||||
|
QString to = from;
|
||||||
|
QString response = QString( tr("I'm sorry -- I'm just an automatic presence used by Tomahawk Player"
|
||||||
|
" (http://gettomahawk.com). If you are getting this message, the person you"
|
||||||
|
" are trying to reach is probably not signed on, so please try again later!") );
|
||||||
|
|
||||||
|
// this is not a sip message, so we send it directly through the client
|
||||||
|
m_client->send( Jreen::Message ( Jreen::Message::Chat, Jreen::JID(to), response) );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << Q_FUNC_INFO << "From:" << message.from().full() << ":" << message.body();
|
||||||
|
emit msgReceived( from, msg );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void JabberPlugin::onNewPresence( const Jreen::Presence& presence)
|
||||||
|
{
|
||||||
|
Jreen::JID jid = presence.from();
|
||||||
|
QString fulljid( jid.full() );
|
||||||
|
|
||||||
|
|
||||||
|
qDebug() << Q_FUNC_INFO << "* New presence: " << fulljid << presence.subtype();
|
||||||
|
|
||||||
|
if( jid == m_client->jid() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ( presence.error() ) {
|
||||||
|
//qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: no" << "presence error";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore anyone not Running tomahawk:
|
||||||
|
Jreen::Capabilities::Ptr caps = presence.findExtension<Jreen::Capabilities>();
|
||||||
|
if ( caps && ( caps->node() == TOMAHAWK_CAP_NODE_NAME ) )
|
||||||
|
{
|
||||||
|
// must be a jreen resource, implementation in gloox was broken
|
||||||
|
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: yes" << "caps " << caps->node();
|
||||||
|
handlePeerStatus( jid, presence.subtype() );
|
||||||
|
}
|
||||||
|
else if( caps )
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: maybe" << "caps " << caps->node()
|
||||||
|
<< "requesting disco..";
|
||||||
|
|
||||||
|
// request disco features
|
||||||
|
QString node = caps->node() + '#' + caps->ver();
|
||||||
|
|
||||||
|
Jreen::IQ iq( Jreen::IQ::Get, jid );
|
||||||
|
iq.addExtension( new Jreen::Disco::Info( node ) );
|
||||||
|
|
||||||
|
m_client->send( iq, this, SLOT( onNewIq( Jreen::IQ, int ) ), RequestDisco );
|
||||||
|
}
|
||||||
|
else if( !caps )
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO << "Running tomahawk: no" << "no caps";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JabberPlugin::onNewIq(const Jreen::IQ& iq, int context)
|
||||||
|
{
|
||||||
|
if( context == RequestDisco )
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO << "Received disco IQ...";
|
||||||
|
Jreen::Disco::Info *discoInfo = iq.findExtension<Jreen::Disco::Info>().data();
|
||||||
|
if(!discoInfo)
|
||||||
|
return;
|
||||||
|
iq.accept();
|
||||||
|
|
||||||
|
Jreen::JID jid = iq.from();
|
||||||
|
|
||||||
|
Jreen::DataForm::Ptr form = discoInfo->form();
|
||||||
|
|
||||||
|
if(discoInfo->features().contains( TOMAHAWK_FEATURE ))
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO << jid.full() << "Running tomahawk/feature enabled: yes";
|
||||||
|
|
||||||
|
// the actual presence doesn't matter, it just needs to be "online"
|
||||||
|
handlePeerStatus( jid, Jreen::Presence::Available );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO << jid.full() << "Running tomahawk/feature enabled: no";
|
||||||
|
|
||||||
|
//LEGACY: accept resources starting with tomahawk too
|
||||||
|
if( jid.resource().startsWith("tomahawk") )
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO << jid.full() << "Detected legacy tomahawk..";
|
||||||
|
|
||||||
|
// add to legacy peers, so we can send text messages instead of iqs
|
||||||
|
m_legacy_peers.append( jid );
|
||||||
|
|
||||||
|
handlePeerStatus( jid, Jreen::Presence::Available );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(context == RequestedDisco)
|
||||||
|
{
|
||||||
|
qDebug() << "Sent IQ(Set), what should be happening here?";
|
||||||
|
}
|
||||||
|
else if(context == SipMessageSent )
|
||||||
|
{
|
||||||
|
qDebug() << "Sent SipMessage... what now?!";
|
||||||
|
}
|
||||||
|
/*else if(context == RequestedVCard )
|
||||||
|
{
|
||||||
|
qDebug() << "Requested VCard... what now?!";
|
||||||
|
}*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
TomahawkSipMessage *sipMessage = iq.findExtension<TomahawkSipMessage>().data();
|
||||||
|
if(sipMessage)
|
||||||
|
{
|
||||||
|
iq.accept();
|
||||||
|
|
||||||
|
qDebug() << Q_FUNC_INFO << "Got SipMessage ...";
|
||||||
|
qDebug() << "ip" << sipMessage->ip();
|
||||||
|
qDebug() << "port" << sipMessage->port();
|
||||||
|
qDebug() << "uniqname" << sipMessage->uniqname();
|
||||||
|
qDebug() << "key" << sipMessage->key();
|
||||||
|
qDebug() << "visible" << sipMessage->visible();
|
||||||
|
|
||||||
|
|
||||||
|
QVariantMap m;
|
||||||
|
if( sipMessage->visible() )
|
||||||
|
{
|
||||||
|
m["visible"] = true;
|
||||||
|
m["ip"] = sipMessage->ip();
|
||||||
|
m["port"] = sipMessage->port();
|
||||||
|
m["key"] = sipMessage->key();
|
||||||
|
m["uniqname"] = sipMessage->uniqname();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m["visible"] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QJson::Serializer ser;
|
||||||
|
QByteArray ba = ser.serialize( m );
|
||||||
|
QString msg = QString::fromAscii( ba );
|
||||||
|
|
||||||
|
QString from = iq.from().full();
|
||||||
|
qDebug() << Q_FUNC_INFO << "From:" << from << ":" << msg;
|
||||||
|
emit msgReceived( from, msg );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool JabberPlugin::presenceMeansOnline(Jreen::Presence::Type p)
|
||||||
|
{
|
||||||
|
switch(p)
|
||||||
|
{
|
||||||
|
case Jreen::Presence::Invalid:
|
||||||
|
case Jreen::Presence::Unavailable:
|
||||||
|
case Jreen::Presence::Error:
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void JabberPlugin::handlePeerStatus(const Jreen::JID& jid, Jreen::Presence::Type presenceType)
|
||||||
|
{
|
||||||
|
QString fulljid = jid.full();
|
||||||
|
|
||||||
|
// "going offline" event
|
||||||
|
if ( !presenceMeansOnline( presenceType ) &&
|
||||||
|
( !m_peers.contains( jid ) ||
|
||||||
|
presenceMeansOnline( m_peers.value( jid ) )
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_peers[ jid ] = presenceType;
|
||||||
|
qDebug() << Q_FUNC_INFO << "* Peer goes offline:" << fulljid;
|
||||||
|
|
||||||
|
// remove peer from legacy peers
|
||||||
|
if( m_legacy_peers.contains( jid ) )
|
||||||
|
{
|
||||||
|
m_legacy_peers.removeAll( jid );
|
||||||
|
}
|
||||||
|
|
||||||
|
emit peerOffline( fulljid );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "coming online" event
|
||||||
|
if( presenceMeansOnline( presenceType ) &&
|
||||||
|
( !m_peers.contains( jid ) ||
|
||||||
|
!presenceMeansOnline( m_peers.value( jid ) )
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
m_peers[ jid ] = presenceType;
|
||||||
|
qDebug() << Q_FUNC_INFO << "* Peer goes online:" << fulljid;
|
||||||
|
|
||||||
|
emit peerOnline( fulljid );
|
||||||
|
|
||||||
|
if(!m_avatarManager->avatar(jid.bare()).isNull())
|
||||||
|
onNewAvatar( jid.bare() );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//qDebug() << "Updating presence data for" << fulljid;
|
||||||
|
m_peers[ jid ] = presenceType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void JabberPlugin::onNewAvatar(const QString& jid)
|
||||||
|
{
|
||||||
|
qDebug() << Q_FUNC_INFO << jid;
|
||||||
|
Q_ASSERT(!m_avatarManager->avatar( jid ).isNull());
|
||||||
|
|
||||||
|
// find peers for the jid
|
||||||
|
QList<Jreen::JID> peers = m_peers.keys();
|
||||||
|
foreach(const Jreen::JID &peer, peers)
|
||||||
|
{
|
||||||
|
if( peer.bare() == jid )
|
||||||
|
{
|
||||||
|
emit avatarReceived ( peer.full(), m_avatarManager->avatar( jid ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( jid == m_client->jid().bare() )
|
||||||
|
// own avatar
|
||||||
|
emit avatarReceived ( m_avatarManager->avatar( jid ) );
|
||||||
|
else
|
||||||
|
// someone else's avatar
|
||||||
|
emit avatarReceived ( jid, m_avatarManager->avatar( jid ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QString
|
QString
|
||||||
JabberPlugin::readPassword()
|
JabberPlugin::readPassword()
|
||||||
{
|
{
|
||||||
|
@@ -21,11 +21,29 @@
|
|||||||
#define JABBER_H
|
#define JABBER_H
|
||||||
|
|
||||||
#include "sip/SipPlugin.h"
|
#include "sip/SipPlugin.h"
|
||||||
#include "jabber_p.h"
|
|
||||||
|
|
||||||
#include "../sipdllmacro.h"
|
#include "avatarmanager.h"
|
||||||
|
|
||||||
|
#include <jreen/client.h>
|
||||||
|
#include <jreen/disco.h>
|
||||||
|
#include <jreen/message.h>
|
||||||
|
#include <jreen/messagesession.h>
|
||||||
|
#include <jreen/stanza.h>
|
||||||
|
#include <jreen/jreen.h>
|
||||||
|
#include <jreen/error.h>
|
||||||
|
#include <jreen/presence.h>
|
||||||
|
#include <jreen/vcard.h>
|
||||||
|
#include <jreen/abstractroster.h>
|
||||||
|
#include <jreen/connection.h>
|
||||||
|
#include <jreen/mucroom.h>
|
||||||
|
|
||||||
|
#include <QNetworkProxy>
|
||||||
|
|
||||||
#define MYNAME "SIPJREEN"
|
#define MYNAME "SIPJREEN"
|
||||||
|
#define TOMAHAWK_FEATURE QLatin1String( "tomahawk:sip:v1" )
|
||||||
|
#define TOMAHAWK_CAP_NODE_NAME QLatin1String( "http://tomahawk-player.org/" )
|
||||||
|
|
||||||
|
#include "../sipdllmacro.h"
|
||||||
|
|
||||||
class Ui_JabberConfig;
|
class Ui_JabberConfig;
|
||||||
|
|
||||||
@@ -64,6 +82,8 @@ public:
|
|||||||
virtual void saveConfig();
|
virtual void saveConfig();
|
||||||
|
|
||||||
void setProxy( QNetworkProxy* proxy );
|
void setProxy( QNetworkProxy* proxy );
|
||||||
|
signals:
|
||||||
|
void jidChanged( const QString& );
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
virtual bool connectPlugin( bool startup );
|
virtual bool connectPlugin( bool startup );
|
||||||
@@ -78,17 +98,31 @@ protected:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void showAddFriendDialog();
|
void showAddFriendDialog();
|
||||||
void onConnected();
|
void onConnect();
|
||||||
void onDisconnected();
|
void onDisconnect(Jreen::Client::DisconnectReason reason);
|
||||||
void onAuthError(int code, const QString &msg);
|
void onAuthError(int code, const QString &msg);
|
||||||
|
|
||||||
|
void onNewPresence( const Jreen::Presence& presence );
|
||||||
|
void onNewMessage( const Jreen::Message& message );
|
||||||
|
void onError( const Jreen::Connection::SocketError& e )
|
||||||
|
{
|
||||||
|
qDebug() << e;
|
||||||
|
}
|
||||||
|
void onNewIq( const Jreen::IQ &iq, int context = NoContext );
|
||||||
|
void onNewAvatar( const QString &jid );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString readPassword();
|
QString readPassword();
|
||||||
QString readServer();
|
QString readServer();
|
||||||
bool readAutoConnect();
|
bool readAutoConnect();
|
||||||
int readPort();
|
int readPort();
|
||||||
|
|
||||||
Jabber_p* p;
|
void addMenuHelper();
|
||||||
|
void removeMenuHelper();
|
||||||
|
|
||||||
|
bool presenceMeansOnline( Jreen::Presence::Type p );
|
||||||
|
void handlePeerStatus( const Jreen::JID &jid, Jreen::Presence::Type presenceType );
|
||||||
|
|
||||||
QMenu* m_menu;
|
QMenu* m_menu;
|
||||||
QAction* m_addFriendAction;
|
QAction* m_addFriendAction;
|
||||||
|
|
||||||
@@ -99,6 +133,18 @@ private:
|
|||||||
ConnectionState m_state;
|
ConnectionState m_state;
|
||||||
|
|
||||||
QWeakPointer< QWidget > m_configWidget;
|
QWeakPointer< QWidget > m_configWidget;
|
||||||
|
|
||||||
|
QString m_currentResource;
|
||||||
|
|
||||||
|
// sort out
|
||||||
|
Jreen::Client *m_client;
|
||||||
|
|
||||||
|
Jreen::MUCRoom *m_room;
|
||||||
|
Jreen::SimpleRoster *m_roster;
|
||||||
|
QHash<Jreen::JID, Jreen::Presence::Type> m_peers;
|
||||||
|
enum IqContext { NoContext, RequestDisco, RequestedDisco, SipMessageSent, RequestedVCard };
|
||||||
|
QStringList m_legacy_peers;
|
||||||
|
AvatarManager *m_avatarManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1,576 +0,0 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
|
||||||
*
|
|
||||||
* Copyright 2010-2011, Dominik Schmidt <dev@dominik-schmidt.de>
|
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
|
||||||
*
|
|
||||||
* 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 "jabber_p.h"
|
|
||||||
#include "tomahawksipmessage.h"
|
|
||||||
#include "tomahawksipmessagefactory.h"
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "utils/tomahawkutils.h"
|
|
||||||
|
|
||||||
#include <jreen/capabilities.h>
|
|
||||||
#include <jreen/tcpconnection.h>
|
|
||||||
#include <jreen/vcardupdate.h>
|
|
||||||
#include <jreen/vcard.h>
|
|
||||||
|
|
||||||
#include <qjson/parser.h>
|
|
||||||
#include <qjson/serializer.h>
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
#include <QTime>
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QString>
|
|
||||||
#include <QRegExp>
|
|
||||||
#include <QThread>
|
|
||||||
#include <QVariant>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QCryptographicHash>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QPixmap>
|
|
||||||
|
|
||||||
//remove
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QtGui/QLabel>
|
|
||||||
|
|
||||||
#define TOMAHAWK_FEATURE QLatin1String( "tomahawk:sip:v1" )
|
|
||||||
|
|
||||||
#define TOMAHAWK_CAP_NODE_NAME QLatin1String( "http://tomahawk-player.org/" )
|
|
||||||
|
|
||||||
Jabber_p::Jabber_p( const QString& jid, const QString& password, const QString& server, const int port )
|
|
||||||
: QObject()
|
|
||||||
, m_server()
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
qsrand(QDateTime::currentDateTime().toTime_t());
|
|
||||||
|
|
||||||
// setup JID object
|
|
||||||
m_jid = Jreen::JID( jid );
|
|
||||||
|
|
||||||
// general client setup
|
|
||||||
m_client = new Jreen::Client( jid, password );
|
|
||||||
if ( !server.isEmpty() )
|
|
||||||
{
|
|
||||||
m_client->setServer( server );
|
|
||||||
m_client->setPort( port );
|
|
||||||
}
|
|
||||||
m_client->registerStanzaExtension(new TomahawkSipMessageFactory);
|
|
||||||
m_client->setResource( QString( "tomahawk%1" ).arg( QString::number( qrand() % 10000 ) ) );
|
|
||||||
|
|
||||||
// add VCardUpdate extension to own presence
|
|
||||||
m_client->presence().addExtension( new Jreen::VCardUpdate() );
|
|
||||||
|
|
||||||
// initialize the AvatarManager
|
|
||||||
m_avatarManager = new AvatarManager(m_client);
|
|
||||||
|
|
||||||
// setup disco
|
|
||||||
m_client->disco()->setSoftwareVersion( "Tomahawk Player", TOMAHAWK_VERSION, CMAKE_SYSTEM );
|
|
||||||
m_client->disco()->addIdentity( Jreen::Disco::Identity( "client", "type", "tomahawk", "en" ) );
|
|
||||||
m_client->disco()->addFeature( TOMAHAWK_FEATURE );
|
|
||||||
|
|
||||||
// setup caps node, legacy peer detection - used before 0.1
|
|
||||||
Jreen::Capabilities::Ptr caps = m_client->presence().findExtension<Jreen::Capabilities>();
|
|
||||||
caps->setNode( TOMAHAWK_CAP_NODE_NAME );
|
|
||||||
|
|
||||||
// print connection parameters
|
|
||||||
qDebug() << "Our JID set to:" << m_client->jid().full();
|
|
||||||
qDebug() << "Our Server set to:" << m_client->server();
|
|
||||||
qDebug() << "Our Port set to" << m_client->port();
|
|
||||||
|
|
||||||
m_client->setConnectionImpl( new Jreen::TcpConnection( m_client->server(), m_client->port() ) );
|
|
||||||
|
|
||||||
// setup slots
|
|
||||||
connect(qobject_cast<Jreen::Connection*>(m_client->connection()), SIGNAL(error(const Jreen::Connection::SocketError&)), SLOT(onError(const Jreen::Connection::SocketError&)));
|
|
||||||
connect(m_client, SIGNAL(serverFeaturesReceived(QSet<QString>)), SLOT(onConnect()));
|
|
||||||
connect(m_client, SIGNAL(disconnected(Jreen::Client::DisconnectReason)), SLOT(onDisconnect(Jreen::Client::DisconnectReason)));
|
|
||||||
connect(m_client, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroy(QObject*)));
|
|
||||||
connect(m_client, SIGNAL(newMessage(Jreen::Message)), SLOT(onNewMessage(Jreen::Message)));
|
|
||||||
connect(m_client, SIGNAL(newPresence(Jreen::Presence)), SLOT(onNewPresence(Jreen::Presence)));
|
|
||||||
connect(m_client, SIGNAL(newIQ(Jreen::IQ)), SLOT(onNewIq(Jreen::IQ)));
|
|
||||||
|
|
||||||
connect(m_avatarManager, SIGNAL(newAvatar(QString)), SLOT(onNewAvatar(QString)));
|
|
||||||
|
|
||||||
|
|
||||||
// connect
|
|
||||||
qDebug() << "Connecting to the XMPP server...";
|
|
||||||
m_client->connectToServer();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Jabber_p::~Jabber_p()
|
|
||||||
{
|
|
||||||
delete m_client;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Jabber_p::setProxy( QNetworkProxy* proxy )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO << "NOT IMPLEMENTED";
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Jabber_p::disconnect()
|
|
||||||
{
|
|
||||||
if ( m_client )
|
|
||||||
{
|
|
||||||
m_client->disconnect();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Jabber_p::sendMsg( const QString& to, const QString& msg )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO << to << msg;
|
|
||||||
|
|
||||||
if ( !m_client ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_legacy_peers.contains( to ) )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO << to << "Send legacy message" << msg;
|
|
||||||
Jreen::Message m( Jreen::Message::Chat, Jreen::JID(to), msg);
|
|
||||||
m_client->send( m );
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*******************************************************
|
|
||||||
* Obsolete this by a SipMessage class
|
|
||||||
*/
|
|
||||||
QJson::Parser parser;
|
|
||||||
bool ok;
|
|
||||||
QVariant v = parser.parse( msg.toAscii(), &ok );
|
|
||||||
if ( !ok || v.type() != QVariant::Map )
|
|
||||||
{
|
|
||||||
qDebug() << "Invalid JSON in XMPP msg";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
QVariantMap m = v.toMap();
|
|
||||||
/*******************************************************/
|
|
||||||
|
|
||||||
TomahawkSipMessage *sipMessage;
|
|
||||||
if(m["visible"].toBool())
|
|
||||||
{
|
|
||||||
sipMessage = new TomahawkSipMessage(m["ip"].toString(),
|
|
||||||
m["port"].toInt(),
|
|
||||||
m["uniqname"].toString(),
|
|
||||||
m["key"].toString(),
|
|
||||||
m["visible"].toBool()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
sipMessage = new TomahawkSipMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
qDebug() << "Send sip messsage to " << to;
|
|
||||||
Jreen::IQ iq( Jreen::IQ::Set, to );
|
|
||||||
iq.addExtension( sipMessage );
|
|
||||||
|
|
||||||
m_client->send( iq, this, SLOT( onNewIq( Jreen::IQ, int ) ), SipMessageSent );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Jabber_p::broadcastMsg( const QString &msg )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
|
|
||||||
if ( !m_client )
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach( const QString& jidstr, m_peers.keys() )
|
|
||||||
{
|
|
||||||
sendMsg( jidstr, msg );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Jabber_p::addContact( const QString& jid, const QString& msg )
|
|
||||||
{
|
|
||||||
// Add contact to the Tomahawk group on the roster
|
|
||||||
m_roster->add( jid, jid, QStringList() << "Tomahawk" );
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Jabber_p::onConnect()
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
|
|
||||||
// update jid resource, servers like gtalk use resource binding and may
|
|
||||||
// have changed our requested /resource
|
|
||||||
if ( m_client->jid().resource() != m_jid.resource() )
|
|
||||||
{
|
|
||||||
// TODO: check if this is still neccessary with jreen
|
|
||||||
m_jid.setResource( m_client->jid().resource() );
|
|
||||||
QString jidstr( m_jid.full() );
|
|
||||||
emit jidChanged( jidstr );
|
|
||||||
}
|
|
||||||
|
|
||||||
emit connected();
|
|
||||||
qDebug() << "Connected as:" << m_jid.full();
|
|
||||||
|
|
||||||
// set presence to least valid value
|
|
||||||
m_client->setPresence(Jreen::Presence::XA, "Got Tomahawk? http://gettomahawk.com", -127);
|
|
||||||
|
|
||||||
// set ping timeout to 15 secs (TODO: verify if this works)
|
|
||||||
m_client->setPingInterval(15000);
|
|
||||||
|
|
||||||
// load roster
|
|
||||||
m_roster = new Jreen::SimpleRoster( m_client );
|
|
||||||
m_roster->load();
|
|
||||||
|
|
||||||
//FIXME: this implementation is totally broken atm, so it's disabled to avoid harm :P
|
|
||||||
// join MUC with bare jid as nickname
|
|
||||||
//TODO: make the room a list of rooms and make that configurable
|
|
||||||
QString mucNickname = QString( "tomahawk@conference.qutim.org/" ).append( QString( m_jid.bare() ).replace( "@", "-" ) );
|
|
||||||
m_room = new Jreen::MUCRoom(m_client, Jreen::JID( mucNickname ) );
|
|
||||||
//m_room->setHistorySeconds(0);
|
|
||||||
//m_room->join();
|
|
||||||
|
|
||||||
// treat muc participiants like contacts
|
|
||||||
connect( m_room, SIGNAL( messageReceived( Jreen::Message, bool ) ), this, SLOT( onNewMessage( Jreen::Message ) ) );
|
|
||||||
connect( m_room, SIGNAL( presenceReceived( Jreen::Presence, const Jreen::MUCRoom::Participant* ) ), this, SLOT( onNewPresence( Jreen::Presence ) ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
Jabber_p::onDisconnect( Jreen::Client::DisconnectReason reason )
|
|
||||||
{
|
|
||||||
QString error;
|
|
||||||
bool reconnect = false;
|
|
||||||
int reconnectInSeconds = 0;
|
|
||||||
|
|
||||||
switch( reason )
|
|
||||||
{
|
|
||||||
case Jreen::Client::User:
|
|
||||||
error = "User Interaction";
|
|
||||||
break;
|
|
||||||
case Jreen::Client::HostUnknown:
|
|
||||||
error = "Host is unknown";
|
|
||||||
break;
|
|
||||||
case Jreen::Client::ItemNotFound:
|
|
||||||
error = "Item not found";
|
|
||||||
break;
|
|
||||||
case Jreen::Client::AuthorizationError:
|
|
||||||
error = "Authorization Error";
|
|
||||||
break;
|
|
||||||
case Jreen::Client::RemoteStreamError:
|
|
||||||
error = "Remote Stream Error";
|
|
||||||
reconnect = true;
|
|
||||||
break;
|
|
||||||
case Jreen::Client::RemoteConnectionFailed:
|
|
||||||
error = "Remote Connection failed";
|
|
||||||
break;
|
|
||||||
case Jreen::Client::InternalServerError:
|
|
||||||
error = "Internal Server Error";
|
|
||||||
reconnect = true;
|
|
||||||
break;
|
|
||||||
case Jreen::Client::SystemShutdown:
|
|
||||||
error = "System shutdown";
|
|
||||||
reconnect = true;
|
|
||||||
reconnectInSeconds = 60;
|
|
||||||
break;
|
|
||||||
case Jreen::Client::Conflict:
|
|
||||||
error = "Conflict";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Jreen::Client::Unknown:
|
|
||||||
error = "Unknown";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
qDebug() << "Not all Client::DisconnectReasons checked";
|
|
||||||
Q_ASSERT(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << "Disconnected from server:" << error;
|
|
||||||
if( reason != Jreen::Client::User )
|
|
||||||
{
|
|
||||||
emit authError( reason, error );
|
|
||||||
}
|
|
||||||
|
|
||||||
if(reconnect)
|
|
||||||
QTimer::singleShot(reconnectInSeconds*1000, m_client, SLOT(connectToServer()));
|
|
||||||
|
|
||||||
emit disconnected();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Jabber_p::onNewMessage( const Jreen::Message& m )
|
|
||||||
{
|
|
||||||
QString from = m.from().full();
|
|
||||||
QString msg = m.body();
|
|
||||||
|
|
||||||
if ( msg.isEmpty() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
QJson::Parser parser;
|
|
||||||
bool ok;
|
|
||||||
QVariant v = parser.parse( msg.toAscii(), &ok );
|
|
||||||
if ( !ok || v.type() != QVariant::Map )
|
|
||||||
{
|
|
||||||
if ( m.from().domain().contains( "googlemail." )
|
|
||||||
|| m.from().domain().contains( "gmail." )
|
|
||||||
|| m.from().domain().contains( "gtalk." )
|
|
||||||
)
|
|
||||||
return;
|
|
||||||
|
|
||||||
QString to = from;
|
|
||||||
QString response = QString( tr("I'm sorry -- I'm just an automatic presence used by Tomahawk Player"
|
|
||||||
" (http://gettomahawk.com). If you are getting this message, the person you"
|
|
||||||
" are trying to reach is probably not signed on, so please try again later!") );
|
|
||||||
|
|
||||||
// this is not a sip message, so we send it directly through the client
|
|
||||||
m_client->send( Jreen::Message ( Jreen::Message::Chat, Jreen::JID(to), response) );
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
qDebug() << Q_FUNC_INFO << "From:" << m.from().full() << ":" << m.body();
|
|
||||||
emit msgReceived( from, msg );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Jabber_p::onNewPresence( const Jreen::Presence& presence)
|
|
||||||
{
|
|
||||||
Jreen::JID jid = presence.from();
|
|
||||||
QString fulljid( jid.full() );
|
|
||||||
|
|
||||||
|
|
||||||
qDebug() << Q_FUNC_INFO << "* New presence: " << fulljid << presence.subtype();
|
|
||||||
|
|
||||||
if( jid == m_jid )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if ( presence.error() ) {
|
|
||||||
//qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: no" << "presence error";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ignore anyone not Running tomahawk:
|
|
||||||
Jreen::Capabilities::Ptr caps = presence.findExtension<Jreen::Capabilities>();
|
|
||||||
if ( caps && ( caps->node() == TOMAHAWK_CAP_NODE_NAME ) )
|
|
||||||
{
|
|
||||||
// must be a jreen resource, implementation in gloox was broken
|
|
||||||
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: yes" << "caps " << caps->node();
|
|
||||||
handlePeerStatus( fulljid, presence.subtype() );
|
|
||||||
}
|
|
||||||
else if( caps )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: maybe" << "caps " << caps->node()
|
|
||||||
<< "requesting disco..";
|
|
||||||
|
|
||||||
// request disco features
|
|
||||||
QString node = caps->node() + '#' + caps->ver();
|
|
||||||
|
|
||||||
Jreen::IQ iq( Jreen::IQ::Get, jid );
|
|
||||||
iq.addExtension( new Jreen::Disco::Info( node ) );
|
|
||||||
|
|
||||||
m_client->send( iq, this, SLOT( onNewIq( Jreen::IQ, int ) ), RequestDisco );
|
|
||||||
}
|
|
||||||
else if( !caps )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO << "Running tomahawk: no" << "no caps";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Jabber_p::onNewIq( const Jreen::IQ &iq, int context )
|
|
||||||
{
|
|
||||||
if( context == RequestDisco )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO << "Received disco IQ...";
|
|
||||||
Jreen::Disco::Info *discoInfo = iq.findExtension<Jreen::Disco::Info>().data();
|
|
||||||
if(!discoInfo)
|
|
||||||
return;
|
|
||||||
iq.accept();
|
|
||||||
|
|
||||||
QString fulljid = iq.from().full();
|
|
||||||
Jreen::DataForm::Ptr form = discoInfo->form();
|
|
||||||
|
|
||||||
if(discoInfo->features().contains( TOMAHAWK_FEATURE ))
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk/feature enabled: yes";
|
|
||||||
|
|
||||||
// the actual presence doesn't matter, it just needs to be "online"
|
|
||||||
handlePeerStatus( fulljid, Jreen::Presence::Available );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk/feature enabled: no";
|
|
||||||
|
|
||||||
//LEGACY: accept resources starting with tomahawk too
|
|
||||||
if( iq.from().resource().startsWith("tomahawk") )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO << fulljid << "Detected legacy tomahawk..";
|
|
||||||
|
|
||||||
// add to legacy peers, so we can send text messages instead of iqs
|
|
||||||
m_legacy_peers.append( fulljid );
|
|
||||||
|
|
||||||
handlePeerStatus( fulljid, Jreen::Presence::Available );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(context == RequestedDisco)
|
|
||||||
{
|
|
||||||
qDebug() << "Sent IQ(Set), what should be happening here?";
|
|
||||||
}
|
|
||||||
else if(context == SipMessageSent )
|
|
||||||
{
|
|
||||||
qDebug() << "Sent SipMessage... what now?!";
|
|
||||||
}
|
|
||||||
/*else if(context == RequestedVCard )
|
|
||||||
{
|
|
||||||
qDebug() << "Requested VCard... what now?!";
|
|
||||||
}*/
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
TomahawkSipMessage *sipMessage = iq.findExtension<TomahawkSipMessage>().data();
|
|
||||||
if(sipMessage)
|
|
||||||
{
|
|
||||||
iq.accept();
|
|
||||||
|
|
||||||
qDebug() << Q_FUNC_INFO << "Got SipMessage ...";
|
|
||||||
qDebug() << "ip" << sipMessage->ip();
|
|
||||||
qDebug() << "port" << sipMessage->port();
|
|
||||||
qDebug() << "uniqname" << sipMessage->uniqname();
|
|
||||||
qDebug() << "key" << sipMessage->key();
|
|
||||||
qDebug() << "visible" << sipMessage->visible();
|
|
||||||
|
|
||||||
|
|
||||||
QVariantMap m;
|
|
||||||
if( sipMessage->visible() )
|
|
||||||
{
|
|
||||||
m["visible"] = true;
|
|
||||||
m["ip"] = sipMessage->ip();
|
|
||||||
m["port"] = sipMessage->port();
|
|
||||||
m["key"] = sipMessage->key();
|
|
||||||
m["uniqname"] = sipMessage->uniqname();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m["visible"] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QJson::Serializer ser;
|
|
||||||
QByteArray ba = ser.serialize( m );
|
|
||||||
QString msg = QString::fromAscii( ba );
|
|
||||||
|
|
||||||
QString from = iq.from().full();
|
|
||||||
qDebug() << Q_FUNC_INFO << "From:" << from << ":" << msg;
|
|
||||||
emit msgReceived( from, msg );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
Jabber_p::presenceMeansOnline( Jreen::Presence::Type p )
|
|
||||||
{
|
|
||||||
switch(p)
|
|
||||||
{
|
|
||||||
case Jreen::Presence::Invalid:
|
|
||||||
case Jreen::Presence::Unavailable:
|
|
||||||
case Jreen::Presence::Error:
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Jabber_p::handlePeerStatus( const Jreen::JID& jid, Jreen::Presence::Type presenceType )
|
|
||||||
{
|
|
||||||
QString fulljid = jid.full();
|
|
||||||
|
|
||||||
// "going offline" event
|
|
||||||
if ( !presenceMeansOnline( presenceType ) &&
|
|
||||||
( !m_peers.contains( fulljid ) ||
|
|
||||||
presenceMeansOnline( m_peers.value( fulljid ) )
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
m_peers[ fulljid ] = presenceType;
|
|
||||||
qDebug() << Q_FUNC_INFO << "* Peer goes offline:" << fulljid;
|
|
||||||
|
|
||||||
// remove peer from legacy peers
|
|
||||||
if( m_legacy_peers.contains( fulljid ) )
|
|
||||||
{
|
|
||||||
m_legacy_peers.removeAll( fulljid );
|
|
||||||
}
|
|
||||||
|
|
||||||
emit peerOffline( fulljid );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// "coming online" event
|
|
||||||
if( presenceMeansOnline( presenceType ) &&
|
|
||||||
( !m_peers.contains( fulljid ) ||
|
|
||||||
!presenceMeansOnline( m_peers.value( fulljid ) )
|
|
||||||
)
|
|
||||||
)
|
|
||||||
{
|
|
||||||
m_peers[ fulljid ] = presenceType;
|
|
||||||
qDebug() << Q_FUNC_INFO << "* Peer goes online:" << fulljid;
|
|
||||||
|
|
||||||
emit peerOnline( fulljid );
|
|
||||||
|
|
||||||
if(!m_avatarManager->avatar(jid.bare()).isNull())
|
|
||||||
onNewAvatar( jid.bare() );
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//qDebug() << "Updating presence data for" << fulljid;
|
|
||||||
m_peers[ fulljid ] = presenceType;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Jabber_p::onNewAvatar(const QString& jid)
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO << jid;
|
|
||||||
Q_ASSERT(!m_avatarManager->avatar( jid ).isNull());
|
|
||||||
|
|
||||||
// find peers for the jid
|
|
||||||
QStringList peers = m_peers.keys();
|
|
||||||
foreach(const QString &peer, peers)
|
|
||||||
{
|
|
||||||
if( peer.startsWith(jid) )
|
|
||||||
{
|
|
||||||
emit avatarReceived ( peer, m_avatarManager->avatar( jid ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( jid == m_client->jid().bare() )
|
|
||||||
// own avatar
|
|
||||||
emit avatarReceived ( m_avatarManager->avatar( jid ) );
|
|
||||||
else
|
|
||||||
// someone else's avatar
|
|
||||||
emit avatarReceived ( jid, m_avatarManager->avatar( jid ) );
|
|
||||||
}
|
|
@@ -1,114 +0,0 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
|
||||||
*
|
|
||||||
* Copyright 2010-2011, Dominik Schmidt <dev@dominik-schmidt.de>
|
|
||||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
|
||||||
*
|
|
||||||
* 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 JABBER_P_H
|
|
||||||
#define JABBER_P_H
|
|
||||||
|
|
||||||
#include "../sipdllmacro.h"
|
|
||||||
|
|
||||||
#include "avatarmanager.h"
|
|
||||||
|
|
||||||
#include <jreen/client.h>
|
|
||||||
#include <jreen/disco.h>
|
|
||||||
#include <jreen/message.h>
|
|
||||||
#include <jreen/messagesession.h>
|
|
||||||
#include <jreen/stanza.h>
|
|
||||||
#include <jreen/jreen.h>
|
|
||||||
#include <jreen/error.h>
|
|
||||||
#include <jreen/presence.h>
|
|
||||||
#include <jreen/vcard.h>
|
|
||||||
#include <jreen/abstractroster.h>
|
|
||||||
#include <jreen/connection.h>
|
|
||||||
#include <jreen/mucroom.h>
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QSharedPointer>
|
|
||||||
#include <QMap>
|
|
||||||
#include <QNetworkProxy>
|
|
||||||
|
|
||||||
|
|
||||||
#if defined( WIN32 ) || defined( _WIN32 )
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class SIPDLLEXPORT Jabber_p :
|
|
||||||
public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit Jabber_p( const QString& jid, const QString& password, const QString& server = "", const int port = -1 );
|
|
||||||
virtual ~Jabber_p();
|
|
||||||
|
|
||||||
void setProxy( QNetworkProxy* proxy );
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void msgReceived( const QString&, const QString& ); //from, msg
|
|
||||||
void peerOnline( const QString& );
|
|
||||||
void peerOffline( const QString& );
|
|
||||||
void connected();
|
|
||||||
void disconnected();
|
|
||||||
void jidChanged( const QString& );
|
|
||||||
void avatarReceived( const QPixmap& avatar );
|
|
||||||
void avatarReceived( const QString&, const QPixmap& avatar );
|
|
||||||
void authError( int, const QString& );
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void sendMsg( const QString& to, const QString& msg );
|
|
||||||
void broadcastMsg( const QString& msg );
|
|
||||||
void addContact( const QString& jid, const QString& msg = QString() );
|
|
||||||
void disconnect();
|
|
||||||
|
|
||||||
void onDisconnect(Jreen::Client::DisconnectReason reason);
|
|
||||||
void onConnect();
|
|
||||||
|
|
||||||
private slots:
|
|
||||||
virtual void onNewPresence( const Jreen::Presence& presence );
|
|
||||||
virtual void onNewMessage( const Jreen::Message& msg );
|
|
||||||
virtual void onError( const Jreen::Connection::SocketError& e )
|
|
||||||
{
|
|
||||||
qDebug() << e;
|
|
||||||
}
|
|
||||||
virtual void onDestroy( QObject */*object*/ )
|
|
||||||
{
|
|
||||||
qDebug() << Q_FUNC_INFO;
|
|
||||||
}
|
|
||||||
virtual void onNewIq( const Jreen::IQ &iq, int context = NoContext );
|
|
||||||
virtual void onNewAvatar( const QString &jid );
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool presenceMeansOnline( Jreen::Presence::Type p );
|
|
||||||
void handlePeerStatus( const Jreen::JID &jid, Jreen::Presence::Type presenceType );
|
|
||||||
|
|
||||||
Jreen::Client *m_client;
|
|
||||||
Jreen::MUCRoom *m_room;
|
|
||||||
Jreen::SimpleRoster *m_roster;
|
|
||||||
Jreen::JID m_jid;
|
|
||||||
QMap<Jreen::Presence::Type, QString> m_presences;
|
|
||||||
QMap<QString, Jreen::Presence::Type> m_peers;
|
|
||||||
QString m_server;
|
|
||||||
|
|
||||||
enum IqContext { NoContext, RequestDisco, RequestedDisco, SipMessageSent, RequestedVCard };
|
|
||||||
|
|
||||||
QStringList m_legacy_peers;
|
|
||||||
|
|
||||||
AvatarManager *m_avatarManager;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // JABBER_H
|
|
@@ -48,6 +48,9 @@
|
|||||||
#include "shortcuthandler.h"
|
#include "shortcuthandler.h"
|
||||||
#include "scanmanager.h"
|
#include "scanmanager.h"
|
||||||
#include "tomahawksettings.h"
|
#include "tomahawksettings.h"
|
||||||
|
#include "globalactionmanager.h"
|
||||||
|
#include "webcollection.h"
|
||||||
|
#include "database/localcollection.h"
|
||||||
|
|
||||||
#include "audio/audioengine.h"
|
#include "audio/audioengine.h"
|
||||||
#include "utils/xspfloader.h"
|
#include "utils/xspfloader.h"
|
||||||
@@ -223,7 +226,7 @@ TomahawkApp::init()
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
qDebug() << "Setting NAM.";
|
qDebug() << "Setting NAM.";
|
||||||
TomahawkUtils::setNam( new QNetworkAccessManager );
|
TomahawkUtils::setNam( new QNetworkAccessManager() );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set up proxy
|
// Set up proxy
|
||||||
@@ -241,7 +244,6 @@ TomahawkApp::init()
|
|||||||
else
|
else
|
||||||
TomahawkUtils::setProxy( new QNetworkProxy( QNetworkProxy::NoProxy ) );
|
TomahawkUtils::setProxy( new QNetworkProxy( QNetworkProxy::NoProxy ) );
|
||||||
|
|
||||||
|
|
||||||
Echonest::Config::instance()->setAPIKey( "JRIHWEP6GPOER2QQ6" );
|
Echonest::Config::instance()->setAPIKey( "JRIHWEP6GPOER2QQ6" );
|
||||||
Echonest::Config::instance()->setNetworkAccessManager( TomahawkUtils::nam() );
|
Echonest::Config::instance()->setNetworkAccessManager( TomahawkUtils::nam() );
|
||||||
|
|
||||||
@@ -249,7 +251,6 @@ TomahawkApp::init()
|
|||||||
|
|
||||||
qDebug() << "Init SIP system.";
|
qDebug() << "Init SIP system.";
|
||||||
|
|
||||||
|
|
||||||
#ifndef TOMAHAWK_HEADLESS
|
#ifndef TOMAHAWK_HEADLESS
|
||||||
if ( !m_headless )
|
if ( !m_headless )
|
||||||
{
|
{
|
||||||
@@ -462,12 +463,19 @@ void
|
|||||||
TomahawkApp::initLocalCollection()
|
TomahawkApp::initLocalCollection()
|
||||||
{
|
{
|
||||||
source_ptr src( new Source( 0, "My Collection" ) );
|
source_ptr src( new Source( 0, "My Collection" ) );
|
||||||
collection_ptr coll( new DatabaseCollection( src ) );
|
collection_ptr coll( new LocalCollection( src ) );
|
||||||
|
|
||||||
src->addCollection( coll );
|
src->addCollection( coll );
|
||||||
SourceList::instance()->setLocal( src );
|
SourceList::instance()->setLocal( src );
|
||||||
// src->collection()->tracks();
|
// src->collection()->tracks();
|
||||||
|
|
||||||
|
// dummy source/collection for web-based result-hints.
|
||||||
|
source_ptr dummy( new Source( -1, "" ) );
|
||||||
|
dummy->setOnline();
|
||||||
|
collection_ptr dummycol( new WebCollection( dummy ) );
|
||||||
|
dummy->addCollection( dummycol );
|
||||||
|
SourceList::instance()->setWebSource( dummy );
|
||||||
|
|
||||||
// to make the stats signal be emitted by our local source
|
// to make the stats signal be emitted by our local source
|
||||||
// this will update the sidebar, etc.
|
// this will update the sidebar, etc.
|
||||||
DatabaseCommand_CollectionStats* cmd = new DatabaseCommand_CollectionStats( src );
|
DatabaseCommand_CollectionStats* cmd = new DatabaseCommand_CollectionStats( src );
|
||||||
@@ -503,7 +511,9 @@ TomahawkApp::setupSIP()
|
|||||||
|
|
||||||
qDebug() << "Connecting SIP classes";
|
qDebug() << "Connecting SIP classes";
|
||||||
SipHandler::instance()->loadFromConfig( true );
|
SipHandler::instance()->loadFromConfig( true );
|
||||||
// SipHandler::instance()->setProxy( *TomahawkUtils::proxy() );
|
|
||||||
|
// m_sipHandler->setProxy( *TomahawkUtils::proxy() );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -520,28 +530,22 @@ TomahawkApp::activate()
|
|||||||
bool
|
bool
|
||||||
TomahawkApp::loadUrl( const QString& url )
|
TomahawkApp::loadUrl( const QString& url )
|
||||||
{
|
{
|
||||||
if( url.contains( "tomahawk://" ) ) {
|
if( url.startsWith( "tomahawk://" ) )
|
||||||
QString cmd = url.mid( 11 );
|
return GlobalActionManager::instance()->parseTomahawkLink( url );
|
||||||
qDebug() << "tomahawk!s" << cmd;
|
else
|
||||||
if( cmd.startsWith( "load/?" ) ) {
|
{
|
||||||
cmd = cmd.mid( 6 );
|
|
||||||
qDebug() << "loading.." << cmd;
|
|
||||||
if( cmd.startsWith( "xspf=" ) ) {
|
|
||||||
XSPFLoader* l = new XSPFLoader( true, this );
|
|
||||||
qDebug() << "Loading spiff:" << cmd.mid( 5 );
|
|
||||||
l->load( QUrl( cmd.mid( 5 ) ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
QFile f( url );
|
QFile f( url );
|
||||||
QFileInfo info( f );
|
QFileInfo info( f );
|
||||||
if( f.exists() && info.suffix() == "xspf" ) {
|
if( f.exists() && info.suffix() == "xspf" ) {
|
||||||
XSPFLoader* l = new XSPFLoader( true, this );
|
XSPFLoader* l = new XSPFLoader( true, this );
|
||||||
qDebug() << "Loading spiff:" << url;
|
qDebug() << "Loading spiff:" << url;
|
||||||
l->load( QUrl::fromUserInput( url ) );
|
l->load( QUrl::fromUserInput( url ) );
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -555,6 +559,7 @@ TomahawkApp::instanceStarted( KDSingleApplicationGuard::Instance instance )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
loadUrl( instance.arguments.at( 1 ) );
|
QString arg1 = instance.arguments[ 1 ];
|
||||||
|
loadUrl( arg1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
#include <QAction>
|
#include <QAction>
|
||||||
#include <QCloseEvent>
|
#include <QCloseEvent>
|
||||||
|
#include <QShowEvent>
|
||||||
|
#include <QHideEvent>
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
#include <QPixmap>
|
#include <QPixmap>
|
||||||
#include <QPropertyAnimation>
|
#include <QPropertyAnimation>
|
||||||
@@ -161,7 +163,7 @@ TomahawkWindow::TomahawkWindow( QWidget* parent )
|
|||||||
|
|
||||||
qtsparkle::Updater* updater = new qtsparkle::Updater( updaterUrl, this );
|
qtsparkle::Updater* updater = new qtsparkle::Updater( updaterUrl, this );
|
||||||
updater->SetNetworkAccessManager( TomahawkUtils::nam() );
|
updater->SetNetworkAccessManager( TomahawkUtils::nam() );
|
||||||
updater->SetVersion( VERSION );
|
updater->SetVersion( TOMAHAWK_VERSION );
|
||||||
|
|
||||||
ui->menu_Help->addSeparator();
|
ui->menu_Help->addSeparator();
|
||||||
QAction* checkForUpdates = ui->menu_Help->addAction( tr( "Check For Updates...") );
|
QAction* checkForUpdates = ui->menu_Help->addAction( tr( "Check For Updates...") );
|
||||||
@@ -267,6 +269,13 @@ TomahawkWindow::setupSignals()
|
|||||||
connect( ui->actionCreate_New_Station, SIGNAL( triggered() ), SLOT( createStation() ));
|
connect( ui->actionCreate_New_Station, SIGNAL( triggered() ), SLOT( createStation() ));
|
||||||
connect( ui->actionAboutTomahawk, SIGNAL( triggered() ), SLOT( showAboutTomahawk() ) );
|
connect( ui->actionAboutTomahawk, SIGNAL( triggered() ), SLOT( showAboutTomahawk() ) );
|
||||||
connect( ui->actionExit, SIGNAL( triggered() ), APP, SLOT( quit() ) );
|
connect( ui->actionExit, SIGNAL( triggered() ), APP, SLOT( quit() ) );
|
||||||
|
#if defined( Q_OS_DARWIN )
|
||||||
|
connect( ui->actionMinimize, SIGNAL( triggered() ), SLOT( minimize() ) );
|
||||||
|
connect( ui->actionZoom, SIGNAL( triggered() ), SLOT( maximize() ) );
|
||||||
|
#else
|
||||||
|
ui->menuWindow->clear();
|
||||||
|
ui->menuWindow->menuAction()->setVisible( false );
|
||||||
|
#endif
|
||||||
|
|
||||||
// <SipHandler>
|
// <SipHandler>
|
||||||
connect( APP->sipHandler(), SIGNAL( connected() ), SLOT( onSipConnected() ) );
|
connect( APP->sipHandler(), SIGNAL( connected() ), SLOT( onSipConnected() ) );
|
||||||
@@ -294,7 +303,6 @@ TomahawkWindow::changeEvent( QEvent* e )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TomahawkWindow::closeEvent( QCloseEvent* e )
|
TomahawkWindow::closeEvent( QCloseEvent* e )
|
||||||
{
|
{
|
||||||
@@ -310,6 +318,27 @@ TomahawkWindow::closeEvent( QCloseEvent* e )
|
|||||||
e->accept();
|
e->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TomahawkWindow::showEvent( QShowEvent* e )
|
||||||
|
{
|
||||||
|
QMainWindow::showEvent( e );
|
||||||
|
|
||||||
|
#if defined( Q_OS_DARWIN )
|
||||||
|
ui->actionMinimize->setDisabled( false );
|
||||||
|
ui->actionZoom->setDisabled( false );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TomahawkWindow::hideEvent( QHideEvent* e )
|
||||||
|
{
|
||||||
|
QMainWindow::hideEvent( e );
|
||||||
|
|
||||||
|
#if defined( Q_OS_DARWIN )
|
||||||
|
ui->actionMinimize->setDisabled( true );
|
||||||
|
ui->actionZoom->setDisabled( true );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TomahawkWindow::showSettingsDialog()
|
TomahawkWindow::showSettingsDialog()
|
||||||
@@ -530,3 +559,25 @@ TomahawkWindow::checkForUpdates()
|
|||||||
Tomahawk::checkForUpdates();
|
Tomahawk::checkForUpdates();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TomahawkWindow::minimize()
|
||||||
|
{
|
||||||
|
if ( isMinimized() )
|
||||||
|
{
|
||||||
|
showNormal();
|
||||||
|
} else {
|
||||||
|
showMinimized();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TomahawkWindow::maximize()
|
||||||
|
{
|
||||||
|
if ( isMaximized() )
|
||||||
|
{
|
||||||
|
showNormal();
|
||||||
|
} else {
|
||||||
|
showMaximized();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -57,6 +57,8 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
void changeEvent( QEvent* e );
|
void changeEvent( QEvent* e );
|
||||||
void closeEvent( QCloseEvent* e );
|
void closeEvent( QCloseEvent* e );
|
||||||
|
void showEvent( QShowEvent* e );
|
||||||
|
void hideEvent( QHideEvent* e );
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void createAutomaticPlaylist();
|
void createAutomaticPlaylist();
|
||||||
@@ -84,6 +86,10 @@ private slots:
|
|||||||
|
|
||||||
void onSipPluginAdded( SipPlugin* p );
|
void onSipPluginAdded( SipPlugin* p );
|
||||||
void onSipPluginRemoved( SipPlugin* p );
|
void onSipPluginRemoved( SipPlugin* p );
|
||||||
|
|
||||||
|
void minimize();
|
||||||
|
void maximize();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loadSettings();
|
void loadSettings();
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
|
@@ -72,6 +72,13 @@
|
|||||||
<addaction name="actionToggleConnect"/>
|
<addaction name="actionToggleConnect"/>
|
||||||
<addaction name="separator"/>
|
<addaction name="separator"/>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuWindow">
|
||||||
|
<property name="title">
|
||||||
|
<string>&Window</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionMinimize"/>
|
||||||
|
<addaction name="actionZoom"/>
|
||||||
|
</widget>
|
||||||
<widget class="QMenu" name="menu_Help">
|
<widget class="QMenu" name="menu_Help">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>&Help</string>
|
<string>&Help</string>
|
||||||
@@ -82,6 +89,7 @@
|
|||||||
<addaction name="menuPlaylist"/>
|
<addaction name="menuPlaylist"/>
|
||||||
<addaction name="menuNetwork"/>
|
<addaction name="menuNetwork"/>
|
||||||
<addaction name="menuSettings"/>
|
<addaction name="menuSettings"/>
|
||||||
|
<addaction name="menuWindow"/>
|
||||||
<addaction name="menu_Help"/>
|
<addaction name="menu_Help"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QStatusBar" name="statusBar"/>
|
<widget class="QStatusBar" name="statusBar"/>
|
||||||
@@ -157,6 +165,22 @@
|
|||||||
<string>Hide Offline Sources</string>
|
<string>Hide Offline Sources</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
|
<action name="actionMinimize">
|
||||||
|
<property name="text">
|
||||||
|
<string>Minimize</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Ctrl+M</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionZoom">
|
||||||
|
<property name="text">
|
||||||
|
<string>Zoom</string>
|
||||||
|
</property>
|
||||||
|
<property name="shortcut">
|
||||||
|
<string>Meta+Ctrl+Z</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
2
thirdparty/jreen
vendored
2
thirdparty/jreen
vendored
Submodule thirdparty/jreen updated: 040ca3f3cb...40fd6b0a3d
5
thirdparty/liblastfm2/src/CMakeLists.txt
vendored
5
thirdparty/liblastfm2/src/CMakeLists.txt
vendored
@@ -78,7 +78,7 @@ if(UNIX)
|
|||||||
endif(APPLE)
|
endif(APPLE)
|
||||||
endif(UNIX)
|
endif(UNIX)
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(SOURCES ${SOURCES} ws/win/WNetworkConnectionMonitor_win.cpp)
|
set(SOURCES ${SOURCES} ws/win/WNetworkConnectionMonitor_win.cpp ws/win/Pac.cpp ws/win/NdisEvents.cpp )
|
||||||
set(MOC_HEADERS ${MOC_HEADERS} ws/win/WNetworkConnectionMonitor.h)
|
set(MOC_HEADERS ${MOC_HEADERS} ws/win/WNetworkConnectionMonitor.h)
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
@@ -100,9 +100,10 @@ ENDIF()
|
|||||||
target_link_libraries(tomahawk_lastfm2
|
target_link_libraries(tomahawk_lastfm2
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
${QT_QTDBUS_LIBRARY}
|
${QT_QTDBUS_LIBRARY}
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set_target_properties(tomahawk_lastfm2 PROPERTIES COMPILE_FLAGS "-DLASTFM_OHAI_QMAKE" )
|
set_target_properties(tomahawk_lastfm2 PROPERTIES COMPILE_FLAGS "-DLASTFM_OHAI_QMAKE" )
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
target_link_libraries(tomahawk_lastfm2
|
target_link_libraries(tomahawk_lastfm2
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2009 Last.fm Ltd.
|
Copyright 2009 Last.fm Ltd.
|
||||||
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
||||||
|
|
||||||
This file is part of liblastfm.
|
This file is part of liblastfm.
|
||||||
@@ -34,11 +34,11 @@
|
|||||||
|
|
||||||
static struct NetworkAccessManagerInit
|
static struct NetworkAccessManagerInit
|
||||||
{
|
{
|
||||||
// We do this upfront because then our Firehose QTcpSocket will have a proxy
|
// We do this upfront because then our Firehose QTcpSocket will have a proxy
|
||||||
// set by default. As well as any plain QNetworkAcessManager stuff, and the
|
// set by default. As well as any plain QNetworkAcessManager stuff, and the
|
||||||
// scrobbler
|
// scrobbler
|
||||||
// In theory we should do this every request in case the configuration
|
// In theory we should do this every request in case the configuration
|
||||||
// changes but that is fairly unlikely use case, init? Maybe we should
|
// changes but that is fairly unlikely use case, init? Maybe we should
|
||||||
// anyway..
|
// anyway..
|
||||||
|
|
||||||
NetworkAccessManagerInit()
|
NetworkAccessManagerInit()
|
||||||
@@ -50,7 +50,7 @@ static struct NetworkAccessManagerInit
|
|||||||
// at two seconds, so that hangs startup
|
// at two seconds, so that hangs startup
|
||||||
if (!s.fAutoDetect && s.lpszProxy)
|
if (!s.fAutoDetect && s.lpszProxy)
|
||||||
{
|
{
|
||||||
QUrl url( QString::fromUtf16(s.lpszProxy) );
|
QUrl url( QString::fromUtf16((const unsigned short*)s.lpszProxy) );
|
||||||
QNetworkProxy proxy( QNetworkProxy::HttpProxy );
|
QNetworkProxy proxy( QNetworkProxy::HttpProxy );
|
||||||
proxy.setHostName( url.host() );
|
proxy.setHostName( url.host() );
|
||||||
proxy.setPort( url.port() );
|
proxy.setPort( url.port() );
|
||||||
@@ -69,10 +69,10 @@ static struct NetworkAccessManagerInit
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
} init;
|
} init;
|
||||||
|
|
||||||
|
|
||||||
namespace lastfm
|
namespace lastfm
|
||||||
{
|
{
|
||||||
LASTFM_DLLEXPORT QByteArray UserAgent;
|
LASTFM_DLLEXPORT QByteArray UserAgent;
|
||||||
}
|
}
|
||||||
@@ -106,12 +106,12 @@ lastfm::NetworkAccessManager::~NetworkAccessManager()
|
|||||||
|
|
||||||
QNetworkProxy
|
QNetworkProxy
|
||||||
lastfm::NetworkAccessManager::proxy( const QNetworkRequest& request )
|
lastfm::NetworkAccessManager::proxy( const QNetworkRequest& request )
|
||||||
{
|
{
|
||||||
Q_UNUSED( request );
|
Q_UNUSED( request );
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
IeSettings s;
|
IeSettings s;
|
||||||
if (s.fAutoDetect)
|
if (s.fAutoDetect)
|
||||||
{
|
{
|
||||||
if (!m_pac) {
|
if (!m_pac) {
|
||||||
m_pac = new Pac;
|
m_pac = new Pac;
|
||||||
@@ -122,9 +122,9 @@ lastfm::NetworkAccessManager::proxy( const QNetworkRequest& request )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return m_pac->resolve( request, s.lpszAutoConfigUrl );
|
return m_pac->resolve( request, s.lpszAutoConfigUrl );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return QNetworkProxy::applicationProxy();
|
return QNetworkProxy::applicationProxy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ lastfm::NetworkAccessManager::createRequest( Operation op, const QNetworkRequest
|
|||||||
|
|
||||||
request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
|
request.setAttribute( QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache );
|
||||||
request.setRawHeader( "User-Agent", lastfm::UserAgent );
|
request.setRawHeader( "User-Agent", lastfm::UserAgent );
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
// PAC proxies can vary by domain, so we have to check everytime :(
|
// PAC proxies can vary by domain, so we have to check everytime :(
|
||||||
QNetworkProxy proxy = this->proxy( request );
|
QNetworkProxy proxy = this->proxy( request );
|
||||||
@@ -152,7 +152,7 @@ void
|
|||||||
lastfm::NetworkAccessManager::onConnectivityChanged( bool up )
|
lastfm::NetworkAccessManager::onConnectivityChanged( bool up )
|
||||||
{
|
{
|
||||||
Q_UNUSED( up );
|
Q_UNUSED( up );
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
if (up && m_pac) m_pac->resetFailedState();
|
if (up && m_pac) m_pac->resetFailedState();
|
||||||
#endif
|
#endif
|
||||||
|
27
thirdparty/liblastfm2/src/ws/win/ComSetup.h
vendored
27
thirdparty/liblastfm2/src/ws/win/ComSetup.h
vendored
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2009 Last.fm Ltd.
|
Copyright 2009 Last.fm Ltd.
|
||||||
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
||||||
|
|
||||||
This file is part of liblastfm.
|
This file is part of liblastfm.
|
||||||
@@ -23,12 +23,13 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <objbase.h>
|
#include <objbase.h>
|
||||||
#include <atlbase.h>
|
//#include <boost/range/atl.hpp>
|
||||||
#include <atlcom.h>
|
//#include <atlbase.h>
|
||||||
|
//#include <atlcom.h>
|
||||||
|
#include <winable.h>
|
||||||
|
|
||||||
/** @brief WsConnectionMonitor needs Com to work as early as possible so we do this
|
/** @brief WsConnectionMonitor needs Com to work as early as possible so we do this
|
||||||
* @author <doug@last.fm>
|
* @author <doug@last.fm>
|
||||||
*/
|
*/
|
||||||
class ComSetup
|
class ComSetup
|
||||||
{
|
{
|
||||||
@@ -37,27 +38,27 @@ public:
|
|||||||
{
|
{
|
||||||
HRESULT hr = CoInitialize(0);
|
HRESULT hr = CoInitialize(0);
|
||||||
m_bComInitialised = SUCCEEDED(hr);
|
m_bComInitialised = SUCCEEDED(hr);
|
||||||
_ASSERT(m_bComInitialised);
|
//_ASSERT(m_bComInitialised);
|
||||||
if (m_bComInitialised) {
|
if (m_bComInitialised) {
|
||||||
setupSecurity();
|
setupSecurity();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupSecurity()
|
void setupSecurity()
|
||||||
{
|
{
|
||||||
CSecurityDescriptor sd;
|
//CSecurityDescriptor sd;
|
||||||
sd.InitializeFromThreadToken();
|
//sd.InitializeFromThreadToken();
|
||||||
HRESULT hr = CoInitializeSecurity(sd, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
|
//HRESULT hr = CoInitializeSecurity(sd, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
|
||||||
_ASSERT(SUCCEEDED(hr));
|
//_ASSERT(SUCCEEDED(hr));
|
||||||
}
|
}
|
||||||
|
|
||||||
~ComSetup()
|
~ComSetup()
|
||||||
{
|
{
|
||||||
if (m_bComInitialised) {
|
if (m_bComInitialised) {
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_bComInitialised;
|
bool m_bComInitialised;
|
||||||
};
|
};
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2009 Last.fm Ltd.
|
Copyright 2009 Last.fm Ltd.
|
||||||
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
||||||
|
|
||||||
This file is part of liblastfm.
|
This file is part of liblastfm.
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
*/
|
*/
|
||||||
struct IeSettings : WINHTTP_CURRENT_USER_IE_PROXY_CONFIG
|
struct IeSettings : WINHTTP_CURRENT_USER_IE_PROXY_CONFIG
|
||||||
{
|
{
|
||||||
|
#ifndef WIN32
|
||||||
IeSettings()
|
IeSettings()
|
||||||
{
|
{
|
||||||
if (!WinHttpGetIEProxyConfigForCurrentUser(this)) {
|
if (!WinHttpGetIEProxyConfigForCurrentUser(this)) {
|
||||||
@@ -33,7 +34,8 @@ struct IeSettings : WINHTTP_CURRENT_USER_IE_PROXY_CONFIG
|
|||||||
lpszAutoConfigUrl = lpszProxy = lpszProxyBypass = 0;
|
lpszAutoConfigUrl = lpszProxy = lpszProxyBypass = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
~IeSettings()
|
~IeSettings()
|
||||||
{
|
{
|
||||||
if (lpszAutoConfigUrl) GlobalFree(lpszAutoConfigUrl);
|
if (lpszAutoConfigUrl) GlobalFree(lpszAutoConfigUrl);
|
||||||
|
26
thirdparty/liblastfm2/src/ws/win/NdisEvents.cpp
vendored
26
thirdparty/liblastfm2/src/ws/win/NdisEvents.cpp
vendored
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2009 Last.fm Ltd.
|
Copyright 2009 Last.fm Ltd.
|
||||||
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
||||||
|
|
||||||
This file is part of liblastfm.
|
This file is part of liblastfm.
|
||||||
@@ -32,35 +32,37 @@ NdisEvents::NdisEvents()
|
|||||||
|
|
||||||
NdisEvents::~NdisEvents()
|
NdisEvents::~NdisEvents()
|
||||||
{
|
{
|
||||||
|
#ifndef WIN32
|
||||||
if (m_pSink)
|
if (m_pSink)
|
||||||
m_pSink->disconnect();
|
m_pSink->disconnect();
|
||||||
if (m_pServices && m_pSink)
|
#endif
|
||||||
m_pServices->CancelAsyncCall(m_pSink);
|
//if (m_pServices && m_pSink)
|
||||||
|
//m_pServices->CancelAsyncCall(m_pSink);
|
||||||
// and reference counting will take care of the WmiSink object
|
// and reference counting will take care of the WmiSink object
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT
|
HRESULT
|
||||||
NdisEvents::registerForNdisEvents()
|
NdisEvents::registerForNdisEvents()
|
||||||
{
|
{
|
||||||
HRESULT hr = m_pLocator.CoCreateInstance(CLSID_WbemLocator);
|
HRESULT hr = 0; //m_pLocator.CoCreateInstance(CLSID_WbemLocator);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
||||||
// Connect to the root\wmi namespace with the current user.
|
// Connect to the root\wmi namespace with the current user.
|
||||||
hr = m_pLocator->ConnectServer(CComBSTR("ROOT\\WMI"), // strNetworkResource
|
hr = 0; /*m_pLocator->ConnectServer(CComBSTR("ROOT\\WMI"), // strNetworkResource
|
||||||
NULL, // strUser
|
NULL, // strUser
|
||||||
NULL, // strPassword
|
NULL, // strPassword
|
||||||
NULL, // strLocale
|
NULL, // strLocale
|
||||||
0, // lSecurityFlags
|
0, // lSecurityFlags
|
||||||
CComBSTR(""), // strAuthority
|
CComBSTR(""), // strAuthority
|
||||||
NULL, // pCtx
|
NULL, // pCtx
|
||||||
&m_pServices
|
&m_pServices
|
||||||
);
|
);*/
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
#ifndef WIN32
|
||||||
m_pSink = new WmiSink(this);
|
m_pSink = new WmiSink(this);
|
||||||
|
#endif
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|
||||||
// other notifications we're not interested in right now include...
|
// other notifications we're not interested in right now include...
|
||||||
@@ -75,12 +77,12 @@ NdisEvents::registerForNdisEvents()
|
|||||||
// MSNdis_StatusProtocolUnbind
|
// MSNdis_StatusProtocolUnbind
|
||||||
// MSNdis_StatusMediaSpecificIndication
|
// MSNdis_StatusMediaSpecificIndication
|
||||||
|
|
||||||
CComBSTR wql("WQL");
|
/*CComBSTR wql("WQL");
|
||||||
CComBSTR query("SELECT * FROM MSNdis_StatusMediaDisconnect");
|
CComBSTR query("SELECT * FROM MSNdis_StatusMediaDisconnect");
|
||||||
hr = m_pServices->ExecNotificationQueryAsync(wql, query, 0, 0, m_pSink);
|
hr = m_pServices->ExecNotificationQueryAsync(wql, query, 0, 0, m_pSink);
|
||||||
|
|
||||||
query = "SELECT * FROM MSNdis_StatusMediaConnect";
|
query = "SELECT * FROM MSNdis_StatusMediaConnect";
|
||||||
hr = m_pServices->ExecNotificationQueryAsync(wql, query, 0, 0, m_pSink);
|
hr = m_pServices->ExecNotificationQueryAsync(wql, query, 0, 0, m_pSink);*/
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
10
thirdparty/liblastfm2/src/ws/win/NdisEvents.h
vendored
10
thirdparty/liblastfm2/src/ws/win/NdisEvents.h
vendored
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2009 Last.fm Ltd.
|
Copyright 2009 Last.fm Ltd.
|
||||||
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
||||||
|
|
||||||
This file is part of liblastfm.
|
This file is part of liblastfm.
|
||||||
@@ -21,8 +21,8 @@
|
|||||||
#define NDIS_EVENTS_H
|
#define NDIS_EVENTS_H
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <atlbase.h>
|
//#include <atlbase.h>
|
||||||
#include <WbemCli.h>
|
//#include <WbemCli.h>
|
||||||
|
|
||||||
class NdisEvents
|
class NdisEvents
|
||||||
{
|
{
|
||||||
@@ -35,8 +35,8 @@ public:
|
|||||||
virtual void onConnectionDown(BSTR name) = 0;
|
virtual void onConnectionDown(BSTR name) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CComPtr<IWbemLocator> m_pLocator;
|
//CComPtr<IWbemLocator> m_pLocator;
|
||||||
CComPtr<IWbemServices> m_pServices;
|
//CComPtr<IWbemServices> m_pServices;
|
||||||
class WmiSink *m_pSink;
|
class WmiSink *m_pSink;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
40
thirdparty/liblastfm2/src/ws/win/Pac.cpp
vendored
40
thirdparty/liblastfm2/src/ws/win/Pac.cpp
vendored
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2009 Last.fm Ltd.
|
Copyright 2009 Last.fm Ltd.
|
||||||
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
||||||
|
|
||||||
This file is part of liblastfm.
|
This file is part of liblastfm.
|
||||||
@@ -21,8 +21,9 @@
|
|||||||
#include <QNetworkRequest>
|
#include <QNetworkRequest>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <atlbase.h>
|
//#include <atlbase.h>
|
||||||
#include <atlconv.h>
|
//#include <atlconv.h>
|
||||||
|
#include <winhttp.h>
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@@ -45,7 +46,7 @@ parsePacServer(const QString &s, QNetworkProxy &p)
|
|||||||
static QList<QNetworkProxy>
|
static QList<QNetworkProxy>
|
||||||
parsePacResult(const QString &pacResult)
|
parsePacResult(const QString &pacResult)
|
||||||
{
|
{
|
||||||
// msdn says: "The proxy server list contains one or more of the
|
// msdn says: "The proxy server list contains one or more of the
|
||||||
// following strings separated by semicolons or whitespace."
|
// following strings separated by semicolons or whitespace."
|
||||||
// ([<scheme>=][<scheme>"://"]<server>[":"<port>])
|
// ([<scheme>=][<scheme>"://"]<server>[":"<port>])
|
||||||
|
|
||||||
@@ -73,8 +74,10 @@ lastfm::Pac::Pac()
|
|||||||
|
|
||||||
lastfm::Pac::~Pac()
|
lastfm::Pac::~Pac()
|
||||||
{
|
{
|
||||||
|
#ifndef WIN32
|
||||||
if (m_hSession)
|
if (m_hSession)
|
||||||
WinHttpCloseHandle(m_hSession);
|
WinHttpCloseHandle(m_hSession);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkProxy
|
QNetworkProxy
|
||||||
@@ -86,42 +89,45 @@ lastfm::Pac::resolve(const QNetworkRequest &request, const wchar_t* pacUrl)
|
|||||||
if (!m_hSession)
|
if (!m_hSession)
|
||||||
{
|
{
|
||||||
QByteArray user_agent = request.rawHeader("user-agent");
|
QByteArray user_agent = request.rawHeader("user-agent");
|
||||||
m_hSession = WinHttpOpen(CA2W(user_agent), WINHTTP_ACCESS_TYPE_NO_PROXY, 0, 0, WINHTTP_FLAG_ASYNC);
|
//m_hSession = WinHttpOpen(CA2W(user_agent), WINHTTP_ACCESS_TYPE_NO_PROXY, 0, 0, WINHTTP_FLAG_ASYNC);
|
||||||
}
|
}
|
||||||
if (m_hSession)
|
if (m_hSession)
|
||||||
{
|
{
|
||||||
WINHTTP_PROXY_INFO info;
|
WINHTTP_PROXY_INFO info;
|
||||||
WINHTTP_AUTOPROXY_OPTIONS opts;
|
WINHTTP_AUTOPROXY_OPTIONS opts;
|
||||||
memset(&opts, 0, sizeof(opts));
|
memset(&opts, 0, sizeof(opts));
|
||||||
if (pacUrl)
|
if (pacUrl)
|
||||||
{
|
{
|
||||||
opts.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
|
//opts.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
|
||||||
opts.lpszAutoConfigUrl = pacUrl;
|
//opts.lpszAutoConfigUrl = pacUrl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
opts.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
|
//opts.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
|
||||||
opts.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
|
//opts.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A;
|
||||||
}
|
}
|
||||||
opts.fAutoLogonIfChallenged = TRUE;
|
opts.fAutoLogonIfChallenged = TRUE;
|
||||||
|
#ifndef WIN32
|
||||||
if (WinHttpGetProxyForUrl(m_hSession, request.url().toString().utf16(), &opts, &info)) {
|
if (WinHttpGetProxyForUrl(m_hSession, (const WCHAR*)(request.url().toString().utf16()), &opts, &info)) {
|
||||||
if (info.lpszProxy)
|
if (info.lpszProxy)
|
||||||
{
|
{
|
||||||
QList<QNetworkProxy> proxies = parsePacResult(QString::fromUtf16(info.lpszProxy));
|
QList<QNetworkProxy> proxies = parsePacResult(QString::fromUtf16((const ushort*)info.lpszProxy));
|
||||||
if (!proxies.empty())
|
if (!proxies.empty())
|
||||||
{
|
{
|
||||||
out = proxies.at(0);
|
out = proxies.at(0);
|
||||||
}
|
}
|
||||||
GlobalFree(info.lpszProxy);
|
// pay attention! casting away constness
|
||||||
|
GlobalFree((void*)info.lpszProxy);
|
||||||
}
|
}
|
||||||
if (info.lpszProxyBypass)
|
if (info.lpszProxyBypass)
|
||||||
{
|
{
|
||||||
GlobalFree(info.lpszProxyBypass);
|
// pay attention! casting away constness
|
||||||
|
GlobalFree((void*)info.lpszProxyBypass);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_bFailed = true;
|
m_bFailed = true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
10
thirdparty/liblastfm2/src/ws/win/Pac.h
vendored
10
thirdparty/liblastfm2/src/ws/win/Pac.h
vendored
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2009 Last.fm Ltd.
|
Copyright 2009 Last.fm Ltd.
|
||||||
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
||||||
|
|
||||||
This file is part of liblastfm.
|
This file is part of liblastfm.
|
||||||
@@ -24,14 +24,14 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <winhttp.h>
|
#include <winhttp.h>
|
||||||
class QNetworkRequest;
|
class QNetworkRequest;
|
||||||
|
|
||||||
namespace lastfm
|
namespace lastfm
|
||||||
{
|
{
|
||||||
/** @brief simple wrapper to do per url automatic proxy detection
|
/** @brief simple wrapper to do per url automatic proxy detection
|
||||||
* @author <doug@last.fm>
|
* @author <doug@last.fm>
|
||||||
*/
|
*/
|
||||||
class Pac
|
class Pac
|
||||||
{
|
{
|
||||||
HINTERNET m_hSession;
|
HINTERNET m_hSession;
|
||||||
bool m_bFailed;
|
bool m_bFailed;
|
||||||
|
|
||||||
@@ -49,4 +49,4 @@ namespace lastfm
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
4
thirdparty/liblastfm2/src/ws/win/WmiSink.h
vendored
4
thirdparty/liblastfm2/src/ws/win/WmiSink.h
vendored
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2009 Last.fm Ltd.
|
Copyright 2009 Last.fm Ltd.
|
||||||
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
- Primarily authored by Max Howell, Jono Cole and Doug Mansell
|
||||||
|
|
||||||
This file is part of liblastfm.
|
This file is part of liblastfm.
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
#ifndef WMISINK_WIN_H
|
#ifndef WMISINK_WIN_H
|
||||||
#define WMISINK_WIN_H
|
#define WMISINK_WIN_H
|
||||||
|
|
||||||
#include "WbemCli.h"
|
#include "wbemcli.h"
|
||||||
|
|
||||||
// Sink object for WMI NDIS notifications
|
// Sink object for WMI NDIS notifications
|
||||||
class WmiSink : public IWbemObjectSink
|
class WmiSink : public IWbemObjectSink
|
||||||
|
34
thirdparty/liblastfm2/src/ws/ws.cpp
vendored
34
thirdparty/liblastfm2/src/ws/ws.cpp
vendored
@@ -25,9 +25,13 @@
|
|||||||
#include <QDomElement>
|
#include <QDomElement>
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
|
#include <QThread>
|
||||||
|
#include <QMutex>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
static QNetworkAccessManager* nam = 0;
|
|
||||||
|
|
||||||
|
static QMap< QThread*, QNetworkAccessManager* > threadNamHash;
|
||||||
|
static QMap< QThread*, bool > ourNamHash;
|
||||||
|
static QMutex namAccessMutex;
|
||||||
|
|
||||||
QString
|
QString
|
||||||
lastfm::ws::host()
|
lastfm::ws::host()
|
||||||
@@ -191,18 +195,34 @@ lastfm::ws::parse( QNetworkReply* reply ) throw( ParseError )
|
|||||||
|
|
||||||
QNetworkAccessManager*
|
QNetworkAccessManager*
|
||||||
lastfm::nam()
|
lastfm::nam()
|
||||||
{
|
{
|
||||||
if (!::nam) ::nam = new NetworkAccessManager( qApp );
|
QMutexLocker l( &namAccessMutex );
|
||||||
return ::nam;
|
QThread* thread = QThread::currentThread();
|
||||||
|
if ( !threadNamHash.contains( thread ) )
|
||||||
|
{
|
||||||
|
NetworkAccessManager* newNam = new NetworkAccessManager();
|
||||||
|
threadNamHash[thread] = newNam;
|
||||||
|
ourNamHash[thread] = true;
|
||||||
|
return newNam;
|
||||||
|
}
|
||||||
|
|
||||||
|
return threadNamHash[thread];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
lastfm::setNetworkAccessManager( QNetworkAccessManager* nam )
|
lastfm::setNetworkAccessManager( QNetworkAccessManager* nam )
|
||||||
{
|
{
|
||||||
delete ::nam;
|
if ( !nam )
|
||||||
::nam = nam;
|
return;
|
||||||
nam->setParent( qApp ); // ensure it isn't deleted out from under us
|
|
||||||
|
QMutexLocker l( &namAccessMutex );
|
||||||
|
QThread* thread = QThread::currentThread();
|
||||||
|
if ( threadNamHash.contains( thread ) && ourNamHash.contains( thread ) && ourNamHash[thread] )
|
||||||
|
delete threadNamHash[thread];
|
||||||
|
|
||||||
|
threadNamHash[thread] = nam;
|
||||||
|
ourNamHash[thread] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user