mirror of
https://github.com/clangen/musikcube.git
synced 2025-02-14 09:40:53 +00:00
- Query::ListSelection and Query::TrackMetadata are fully working with Library::Remote.
- Fixed a tracklist issue where the tracklist where sending 1 query for each track. - Threading issues fixed in Library::Remote and server::Connection.
This commit is contained in:
parent
621afdf5cc
commit
c12a02487b
@ -141,7 +141,7 @@ utfstring musik::core::GetPath(const utfstring &sFile){
|
|||||||
///\returns
|
///\returns
|
||||||
///Converted string
|
///Converted string
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
std::string musik::core::ConvertUTF8(std::wstring &sString){
|
std::string musik::core::ConvertUTF8(const std::wstring &sString){
|
||||||
std::string sUTF8;
|
std::string sUTF8;
|
||||||
utf8::utf16to8(sString.begin(),sString.end(),std::back_inserter(sUTF8));
|
utf8::utf16to8(sString.begin(),sString.end(),std::back_inserter(sUTF8));
|
||||||
return sUTF8;
|
return sUTF8;
|
||||||
@ -157,7 +157,7 @@ std::string musik::core::ConvertUTF8(std::wstring &sString){
|
|||||||
///\returns
|
///\returns
|
||||||
///Converted string
|
///Converted string
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
std::wstring musik::core::ConvertUTF16(std::string &sString){
|
std::wstring musik::core::ConvertUTF16(const std::string &sString){
|
||||||
std::wstring sUTF16;
|
std::wstring sUTF16;
|
||||||
utf8::utf8to16(sString.begin(),sString.end(),std::back_inserter(sUTF16));
|
utf8::utf8to16(sString.begin(),sString.end(),std::back_inserter(sUTF16));
|
||||||
return sUTF16;
|
return sUTF16;
|
||||||
|
@ -61,8 +61,8 @@ namespace musik{ namespace core{
|
|||||||
*****************************/
|
*****************************/
|
||||||
utfstring GetPluginDirectory();
|
utfstring GetPluginDirectory();
|
||||||
|
|
||||||
std::string ConvertUTF8(std::wstring &sString);
|
std::string ConvertUTF8(const std::wstring &sString);
|
||||||
std::wstring ConvertUTF16(std::string &sString);
|
std::wstring ConvertUTF16(const std::string &sString);
|
||||||
std::wstring ConvertUTF16(const char *string);
|
std::wstring ConvertUTF16(const char *string);
|
||||||
|
|
||||||
UINT64 Checksum(char *data,unsigned int bytes);
|
UINT64 Checksum(char *data,unsigned int bytes);
|
||||||
|
@ -144,6 +144,7 @@ utfstring Library::Base::GetDBPath(){
|
|||||||
/// - Query::Options::CancelQueue : Cancel all other queries that are to be executed by the Library.
|
/// - Query::Options::CancelQueue : Cancel all other queries that are to be executed by the Library.
|
||||||
/// - Query::Options::CancelSimilar : Cancel all similar queries. A similar query is a query that originates from the same Query::Base that is passed to the AddQuery.
|
/// - Query::Options::CancelSimilar : Cancel all similar queries. A similar query is a query that originates from the same Query::Base that is passed to the AddQuery.
|
||||||
/// - Query::Options::UnCanceable : Under no circumstances is this Query allowed to be canceled.
|
/// - Query::Options::UnCanceable : Under no circumstances is this Query allowed to be canceled.
|
||||||
|
/// - Query::Options::UnCanceable : Under no circumstances is this Query allowed to be canceled.
|
||||||
///
|
///
|
||||||
///The query will be copied by the library and executed in the library thread.
|
///The query will be copied by the library and executed in the library thread.
|
||||||
///
|
///
|
||||||
@ -159,6 +160,11 @@ bool Library::Base::AddQuery( const Query::Base &query,unsigned int options ){
|
|||||||
// Start by making a copy
|
// Start by making a copy
|
||||||
Query::Ptr queryCopy( query.copy() );
|
Query::Ptr queryCopy( query.copy() );
|
||||||
|
|
||||||
|
//
|
||||||
|
if(options&Query::CopyUniqueId){
|
||||||
|
queryCopy->uniqueId = query.uniqueId;
|
||||||
|
}
|
||||||
|
|
||||||
queryCopy->PreAddQuery(this);
|
queryCopy->PreAddQuery(this);
|
||||||
|
|
||||||
// Since query is not added to queue yet, variables can now be changed without locking.
|
// Since query is not added to queue yet, variables can now be changed without locking.
|
||||||
|
@ -125,9 +125,12 @@ void Library::Remote::ReadThread(){
|
|||||||
boost::system::error_code error = boost::asio::error::host_not_found;
|
boost::system::error_code error = boost::asio::error::host_not_found;
|
||||||
while (error && endpointIterator!=end){
|
while (error && endpointIterator!=end){
|
||||||
this->socket.close();
|
this->socket.close();
|
||||||
this->socket.connect(*endpointIterator++, error);
|
this->socket.connect(*endpointIterator, error);
|
||||||
|
if(error){
|
||||||
|
endpointIterator++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (error){
|
if (error || endpointIterator==end){
|
||||||
this->Exit();
|
this->Exit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -159,6 +162,7 @@ void Library::Remote::ReadThread(){
|
|||||||
if(node.Name()=="queryresults"){
|
if(node.Name()=="queryresults"){
|
||||||
|
|
||||||
unsigned int queryId = boost::lexical_cast<unsigned int>(node.Attributes()["id"]);
|
unsigned int queryId = boost::lexical_cast<unsigned int>(node.Attributes()["id"]);
|
||||||
|
unsigned int uniqueId = boost::lexical_cast<unsigned int>(node.Attributes()["uid"]);
|
||||||
Query::Ptr currentQuery;
|
Query::Ptr currentQuery;
|
||||||
// This is a query node
|
// This is a query node
|
||||||
// Find the query in the outgoingQueries list
|
// Find the query in the outgoingQueries list
|
||||||
@ -166,15 +170,17 @@ void Library::Remote::ReadThread(){
|
|||||||
boost::mutex::scoped_lock lock(this->libraryMutex);
|
boost::mutex::scoped_lock lock(this->libraryMutex);
|
||||||
// Reverse loop since it's most likely the query is in the end
|
// Reverse loop since it's most likely the query is in the end
|
||||||
for(QueryList::reverse_iterator query=this->outgoingQueries.rbegin();query!=this->outgoingQueries.rend();++query){
|
for(QueryList::reverse_iterator query=this->outgoingQueries.rbegin();query!=this->outgoingQueries.rend();++query){
|
||||||
if( (*query)->queryId==queryId ){
|
if( (*query)->uniqueId==uniqueId ){
|
||||||
currentQuery = *query;
|
currentQuery = *query;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(currentQuery){
|
if(currentQuery){
|
||||||
if(currentQuery->RecieveResults(node,this)){
|
if(currentQuery->RecieveResults(node,this)){
|
||||||
|
boost::mutex::scoped_lock lock(this->libraryMutex);
|
||||||
currentQuery->status |= Query::Base::Status::Ended;
|
currentQuery->status |= Query::Base::Status::Ended;
|
||||||
}else{
|
}else{
|
||||||
|
boost::mutex::scoped_lock lock(this->libraryMutex);
|
||||||
currentQuery->status |= Query::Base::Status::Canceled | Query::Base::Status::Ended;
|
currentQuery->status |= Query::Base::Status::Canceled | Query::Base::Status::Ended;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,7 +220,7 @@ void Library::Remote::WriteThread(){
|
|||||||
this->outgoingQueries.push_back(query);
|
this->outgoingQueries.push_back(query);
|
||||||
|
|
||||||
// Set query as started
|
// Set query as started
|
||||||
// query->status |= Query::Base::Status::Started;
|
query->status |= Query::Base::Status::Started;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -222,6 +228,7 @@ void Library::Remote::WriteThread(){
|
|||||||
xml::WriterNode queryNode(rootNode,"query");
|
xml::WriterNode queryNode(rootNode,"query");
|
||||||
queryNode.Attributes()["type"] = query->Name();
|
queryNode.Attributes()["type"] = query->Name();
|
||||||
queryNode.Attributes()["id"] = boost::lexical_cast<std::string>(query->queryId);
|
queryNode.Attributes()["id"] = boost::lexical_cast<std::string>(query->queryId);
|
||||||
|
queryNode.Attributes()["uid"] = boost::lexical_cast<std::string>(query->uniqueId);
|
||||||
|
|
||||||
if(query->options){
|
if(query->options){
|
||||||
queryNode.Attributes()["options"] = boost::lexical_cast<std::string>(query->options);
|
queryNode.Attributes()["options"] = boost::lexical_cast<std::string>(query->options);
|
||||||
@ -233,6 +240,10 @@ void Library::Remote::WriteThread(){
|
|||||||
query->status |= Query::Base::Status::Canceled | Query::Base::Status::Ended;
|
query->status |= Query::Base::Status::Canceled | Query::Base::Status::Ended;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Notify that the Query is finished.
|
||||||
|
this->waitCondition.notify_all();
|
||||||
|
|
||||||
// Check if writer has quit
|
// Check if writer has quit
|
||||||
if(writer.Exited()){
|
if(writer.Exited()){
|
||||||
this->Exit();
|
this->Exit();
|
||||||
@ -265,3 +276,15 @@ void Library::Remote::CancelCurrentQuery( ){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Library::Remote::Exit(){
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(this->libraryMutex);
|
||||||
|
if(!this->exit){
|
||||||
|
if(this->socket.is_open()){
|
||||||
|
this->socket.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this->exit = true;
|
||||||
|
}
|
||||||
|
this->waitCondition.notify_all();
|
||||||
|
}
|
||||||
|
@ -70,6 +70,7 @@ class Remote : public Library::Base{
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void CancelCurrentQuery( );
|
void CancelCurrentQuery( );
|
||||||
|
virtual void Exit();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Methods:
|
// Methods:
|
||||||
|
@ -38,18 +38,22 @@
|
|||||||
|
|
||||||
#include <core/Query/Base.h>
|
#include <core/Query/Base.h>
|
||||||
#include <core/Library/Base.h>
|
#include <core/Library/Base.h>
|
||||||
|
#include <core/xml/ParserNode.h>
|
||||||
|
#include <core/xml/WriterNode.h>
|
||||||
|
|
||||||
using namespace musik::core;
|
using namespace musik::core;
|
||||||
|
|
||||||
Query::Base::Base(void)
|
Query::Base::Base(void)
|
||||||
:status(0)
|
:status(0)
|
||||||
,options(0)
|
,options(0)
|
||||||
|
,uniqueId(0)
|
||||||
{
|
{
|
||||||
// This will guarantee that the query id is uniq for each query, but copies will not.
|
// This will guarantee that the query id is uniq for each query, but copies will not.
|
||||||
// This is usefull when canceling similar queries
|
// This is usefull when canceling similar queries
|
||||||
static unsigned int uniqueQueryId(0);
|
static unsigned int uniqueQueryId(0);
|
||||||
uniqueQueryId++;
|
uniqueQueryId++;
|
||||||
this->queryId = uniqueQueryId;
|
this->queryId = uniqueQueryId;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Query::Base::~Base(void){
|
Query::Base::~Base(void){
|
||||||
@ -114,3 +118,10 @@ bool Query::Base::SendResults(musik::core::xml::WriterNode &queryNode,Library::B
|
|||||||
std::string Query::Base::Name(){
|
std::string Query::Base::Name(){
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Query::Base::PostCopy(){
|
||||||
|
static unsigned int uniqueQueryId(0);
|
||||||
|
uniqueQueryId++;
|
||||||
|
this->uniqueId = uniqueQueryId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,10 @@ namespace musik{ namespace core{
|
|||||||
namespace server{
|
namespace server{
|
||||||
class Connection;
|
class Connection;
|
||||||
}
|
}
|
||||||
|
namespace xml{
|
||||||
|
class ParserNode;
|
||||||
|
class WriterNode;
|
||||||
|
}
|
||||||
} }
|
} }
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -57,8 +61,6 @@ namespace musik{ namespace core{
|
|||||||
#include <sigslot/sigslot.h>
|
#include <sigslot/sigslot.h>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
#include <core/xml/ParserNode.h>
|
|
||||||
#include <core/xml/WriterNode.h>
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -74,7 +76,8 @@ enum Options:unsigned int{
|
|||||||
Prioritize = 4,
|
Prioritize = 4,
|
||||||
CancelQueue = 8,
|
CancelQueue = 8,
|
||||||
CancelSimilar = 16,
|
CancelSimilar = 16,
|
||||||
UnCanceable = 32
|
UnCanceable = 32,
|
||||||
|
CopyUniqueId = 64
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
@ -122,6 +125,7 @@ class Base : public sigslot::has_slots<> {
|
|||||||
///Used for comparing queries and find similar queries.
|
///Used for comparing queries and find similar queries.
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
unsigned int queryId;
|
unsigned int queryId;
|
||||||
|
unsigned int uniqueId;
|
||||||
|
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
///\brief
|
///\brief
|
||||||
@ -205,6 +209,9 @@ class Base : public sigslot::has_slots<> {
|
|||||||
virtual bool SendQuery(musik::core::xml::WriterNode &queryNode);
|
virtual bool SendQuery(musik::core::xml::WriterNode &queryNode);
|
||||||
virtual bool RecieveResults(musik::core::xml::ParserNode &queryNode,Library::Base *library);
|
virtual bool RecieveResults(musik::core::xml::ParserNode &queryNode,Library::Base *library);
|
||||||
virtual bool SendResults(musik::core::xml::WriterNode &queryNode,Library::Base *library);
|
virtual bool SendResults(musik::core::xml::WriterNode &queryNode,Library::Base *library);
|
||||||
|
|
||||||
|
public:
|
||||||
|
void PostCopy();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,6 +38,8 @@
|
|||||||
#include <core/Query/ListBase.h>
|
#include <core/Query/ListBase.h>
|
||||||
#include <core/Library/Base.h>
|
#include <core/Library/Base.h>
|
||||||
#include <core/Common.h>
|
#include <core/Common.h>
|
||||||
|
#include <core/xml/ParserNode.h>
|
||||||
|
#include <core/xml/WriterNode.h>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
using namespace musik::core;
|
using namespace musik::core;
|
||||||
@ -384,4 +386,54 @@ void Query::ListBase::DummySlotTrackInfo(UINT64,UINT64,UINT64){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Query::ListBase::RecieveQueryStandardNodes(musik::core::xml::ParserNode &node){
|
||||||
|
if(node.Name()=="listeners"){
|
||||||
|
|
||||||
|
// Wait for all content
|
||||||
|
node.WaitForContent();
|
||||||
|
|
||||||
|
// Secondly, lets look for what to query for
|
||||||
|
// Split comaseparated list
|
||||||
|
typedef std::vector<std::string> StringVector;
|
||||||
|
StringVector keys;
|
||||||
|
boost::algorithm::split(keys,node.Content(),boost::algorithm::is_any_of(","));
|
||||||
|
|
||||||
|
for(StringVector::iterator key=keys.begin();key!=keys.end();++key){
|
||||||
|
if(!key->empty()){
|
||||||
|
// connect dummy to the signals
|
||||||
|
this->OnMetadataEvent(key->c_str()).connect( (Query::ListBase*)this,&Query::ListBase::DummySlot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(node.Name()=="listtracks"){
|
||||||
|
this->OnTrackEvent().connect( (Query::ListBase*)this,&Query::ListBase::DummySlotTracks);
|
||||||
|
}else if(node.Name()=="listtrackinfo"){
|
||||||
|
this->OnTrackInfoEvent().connect( (Query::ListBase*)this,&Query::ListBase::DummySlotTrackInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <listeners>genre,artist,album</listeners>
|
||||||
|
bool Query::ListBase::SendQueryStandardNodes(musik::core::xml::WriterNode &queryNode){
|
||||||
|
// Then the listeners
|
||||||
|
xml::WriterNode listenersNode(queryNode,"listeners");
|
||||||
|
for(MetadataSignals::iterator listener=this->metadataEvent.begin();listener!=this->metadataEvent.end();++listener){
|
||||||
|
if( listener->second.has_connections() ){
|
||||||
|
if(!listenersNode.Content().empty()){
|
||||||
|
listenersNode.Content().append(",");
|
||||||
|
}
|
||||||
|
listenersNode.Content().append(listener->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Then the track listener
|
||||||
|
if( this->trackEvent.has_connections() ){
|
||||||
|
xml::WriterNode listTracksNode(queryNode,"listtracks");
|
||||||
|
listTracksNode.Content().append("true");
|
||||||
|
}
|
||||||
|
// Then the track listener
|
||||||
|
if( this->trackInfoEvent.has_connections() ){
|
||||||
|
xml::WriterNode listTrackInfoNode(queryNode,"listtrackinfo");
|
||||||
|
listTrackInfoNode.Content().append("true");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -49,10 +49,6 @@
|
|||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
/*namespace musik{ namespace core{
|
|
||||||
class Track;
|
|
||||||
} }
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
namespace musik{ namespace core{
|
namespace musik{ namespace core{
|
||||||
@ -78,6 +74,9 @@ namespace musik{ namespace core{
|
|||||||
|
|
||||||
bool ParseTracksSQL(std::string sql,Library::Base *library,db::Connection &db);
|
bool ParseTracksSQL(std::string sql,Library::Base *library,db::Connection &db);
|
||||||
|
|
||||||
|
bool RecieveQueryStandardNodes(musik::core::xml::ParserNode &node);
|
||||||
|
bool SendQueryStandardNodes(musik::core::xml::WriterNode &queryNode);
|
||||||
|
|
||||||
MetadataResults metadataResults;
|
MetadataResults metadataResults;
|
||||||
TrackVector trackResults;
|
TrackVector trackResults;
|
||||||
|
|
||||||
|
@ -37,6 +37,8 @@
|
|||||||
#include "pch.hpp"
|
#include "pch.hpp"
|
||||||
#include <core/Query/ListSelection.h>
|
#include <core/Query/ListSelection.h>
|
||||||
#include <core/Library/Base.h>
|
#include <core/Library/Base.h>
|
||||||
|
#include <core/xml/ParserNode.h>
|
||||||
|
#include <core/xml/WriterNode.h>
|
||||||
|
|
||||||
#include <boost/format.hpp>
|
#include <boost/format.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
@ -459,7 +461,9 @@ bool Query::ListSelection::ParseQuery(Library::Base *library,db::Connection &db)
|
|||||||
///A shared_ptr to the Query::Base
|
///A shared_ptr to the Query::Base
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
Query::Ptr Query::ListSelection::copy() const{
|
Query::Ptr Query::ListSelection::copy() const{
|
||||||
return Query::Ptr(new Query::ListSelection(*this));
|
Query::Ptr queryCopy(new Query::ListSelection(*this));
|
||||||
|
queryCopy->PostCopy();
|
||||||
|
return queryCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Query::ListSelection::SQLPrependWhereOrAnd(std::string &sql){
|
void Query::ListSelection::SQLPrependWhereOrAnd(std::string &sql){
|
||||||
@ -571,12 +575,10 @@ bool Query::ListSelection::RecieveQuery(musik::core::xml::ParserNode &queryNode)
|
|||||||
|
|
||||||
while( musik::core::xml::ParserNode node = queryNode.ChildNode() ){
|
while( musik::core::xml::ParserNode node = queryNode.ChildNode() ){
|
||||||
if(node.Name()=="selections"){
|
if(node.Name()=="selections"){
|
||||||
std::cout << "<selections>";
|
|
||||||
// Get metakey nodes
|
// Get metakey nodes
|
||||||
// Expected tag is likle this:
|
// Expected tag is likle this:
|
||||||
// <selection key="genre">2,5,3</selection>
|
// <selection key="genre">2,5,3</selection>
|
||||||
while( musik::core::xml::ParserNode selectionNode = node.ChildNode("selection") ){
|
while( musik::core::xml::ParserNode selectionNode = node.ChildNode("selection") ){
|
||||||
std::cout << "<selection key=\"" << selectionNode.Attributes()["key"] << "\">";
|
|
||||||
|
|
||||||
// Wait for all content
|
// Wait for all content
|
||||||
selectionNode.WaitForContent();
|
selectionNode.WaitForContent();
|
||||||
@ -588,34 +590,12 @@ bool Query::ListSelection::RecieveQuery(musik::core::xml::ParserNode &queryNode)
|
|||||||
|
|
||||||
for(StringVector::iterator value=values.begin();value!=values.end();++value){
|
for(StringVector::iterator value=values.begin();value!=values.end();++value){
|
||||||
this->SelectMetadata(selectionNode.Attributes()["key"].c_str(),boost::lexical_cast<DBINT>(*value));
|
this->SelectMetadata(selectionNode.Attributes()["key"].c_str(),boost::lexical_cast<DBINT>(*value));
|
||||||
std::cout << "," << *value;
|
|
||||||
}
|
}
|
||||||
std::cout << "</selection>" << std::endl;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
std::cout << "</selections>" << std::endl;
|
|
||||||
|
|
||||||
}else if(node.Name()=="listeners"){
|
}else{
|
||||||
|
this->RecieveQueryStandardNodes(node);
|
||||||
// Wait for all content
|
|
||||||
node.WaitForContent();
|
|
||||||
|
|
||||||
// Secondly, lets look for what to query for
|
|
||||||
// Split comaseparated list
|
|
||||||
typedef std::vector<std::string> StringVector;
|
|
||||||
StringVector keys;
|
|
||||||
boost::algorithm::split(keys,node.Content(),boost::algorithm::is_any_of(","));
|
|
||||||
|
|
||||||
for(StringVector::iterator key=keys.begin();key!=keys.end();++key){
|
|
||||||
if(!key->empty()){
|
|
||||||
// connect dummy to the signals
|
|
||||||
this->OnMetadataEvent(key->c_str()).connect( (Query::ListBase*)this,&Query::ListBase::DummySlot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else if(node.Name()=="listtracks"){
|
|
||||||
this->OnTrackEvent().connect( (Query::ListBase*)this,&Query::ListBase::DummySlotTracks);
|
|
||||||
}else if(node.Name()=="listtrackinfo"){
|
|
||||||
this->OnTrackInfoEvent().connect( (Query::ListBase*)this,&Query::ListBase::DummySlotTrackInfo);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -625,12 +605,11 @@ std::string Query::ListSelection::Name(){
|
|||||||
return "ListSelection";
|
return "ListSelection";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Query::ListSelection::SendQuery(musik::core::xml::WriterNode &queryNode){
|
|
||||||
/// <selections>
|
/// <selections>
|
||||||
/// <selection key="genre">1,3,5,7</selection>
|
/// <selection key="genre">1,3,5,7</selection>
|
||||||
/// <selection key="artist">6,7,8</selection>
|
/// <selection key="artist">6,7,8</selection>
|
||||||
/// </selections>
|
/// </selections>
|
||||||
/// <listeners>genre,artist,album</listeners>
|
bool Query::ListSelection::SendQuery(musik::core::xml::WriterNode &queryNode){
|
||||||
xml::WriterNode selectionsNode(queryNode,"selections");
|
xml::WriterNode selectionsNode(queryNode,"selections");
|
||||||
|
|
||||||
// Start with the selection nodes
|
// Start with the selection nodes
|
||||||
@ -651,26 +630,8 @@ bool Query::ListSelection::SendQuery(musik::core::xml::WriterNode &queryNode){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Then the listeners
|
this->SendQueryStandardNodes(queryNode);
|
||||||
xml::WriterNode listenersNode(queryNode,"listeners");
|
|
||||||
for(MetadataSignals::iterator listener=this->metadataEvent.begin();listener!=this->metadataEvent.end();++listener){
|
|
||||||
if( listener->second.has_connections() ){
|
|
||||||
if(!listenersNode.Content().empty()){
|
|
||||||
listenersNode.Content().append(",");
|
|
||||||
}
|
|
||||||
listenersNode.Content().append(listener->first);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Then the track listener
|
|
||||||
if( this->trackEvent.has_connections() ){
|
|
||||||
xml::WriterNode listTracksNode(queryNode,"listtracks");
|
|
||||||
listTracksNode.Content().append("true");
|
|
||||||
}
|
|
||||||
// Then the track listener
|
|
||||||
if( this->trackInfoEvent.has_connections() ){
|
|
||||||
xml::WriterNode listTrackInfoNode(queryNode,"listtrackinfo");
|
|
||||||
listTrackInfoNode.Content().append("true");
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,11 +39,7 @@
|
|||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
namespace musik{ namespace core{
|
|
||||||
namespace Library{
|
|
||||||
class Base;
|
|
||||||
}
|
|
||||||
} }
|
|
||||||
//////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
@ -38,6 +38,9 @@
|
|||||||
#include <core/Query/SortTracks.h>
|
#include <core/Query/SortTracks.h>
|
||||||
#include <core/Library/Base.h>
|
#include <core/Library/Base.h>
|
||||||
#include <core/config_format.h>
|
#include <core/config_format.h>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <core/xml/ParserNode.h>
|
||||||
|
#include <core/xml/WriterNode.h>
|
||||||
|
|
||||||
using namespace musik::core;
|
using namespace musik::core;
|
||||||
|
|
||||||
@ -177,7 +180,9 @@ bool Query::SortTracks::ParseQuery(Library::Base *library,db::Connection &db){
|
|||||||
///A shared_ptr to the Query::Base
|
///A shared_ptr to the Query::Base
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
Query::Ptr Query::SortTracks::copy() const{
|
Query::Ptr Query::SortTracks::copy() const{
|
||||||
return Query::Ptr(new Query::SortTracks(*this));
|
Query::Ptr queryCopy(new Query::SortTracks(*this));
|
||||||
|
queryCopy->PostCopy();
|
||||||
|
return queryCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Query::SortTracks::AddTrack(int trackId){
|
void Query::SortTracks::AddTrack(int trackId){
|
||||||
@ -207,3 +212,68 @@ void Query::SortTracks::ClearTracks(){
|
|||||||
this->tracksToSort.clear();
|
this->tracksToSort.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////
|
||||||
|
///\brief
|
||||||
|
///Recieve the query from XML
|
||||||
|
///
|
||||||
|
///\param queryNode
|
||||||
|
///Reference to query XML node
|
||||||
|
///
|
||||||
|
///The excpeted input format is like this:
|
||||||
|
///\code
|
||||||
|
///<query type="SortTracks">
|
||||||
|
/// <tracks>1,3,5,7</tracks>
|
||||||
|
///</query>
|
||||||
|
///\endcode
|
||||||
|
///
|
||||||
|
///\returns
|
||||||
|
///true when successfully recieved
|
||||||
|
//////////////////////////////////////////
|
||||||
|
bool Query::SortTracks::RecieveQuery(musik::core::xml::ParserNode &queryNode){
|
||||||
|
|
||||||
|
while( musik::core::xml::ParserNode node = queryNode.ChildNode() ){
|
||||||
|
if(node.Name()=="tracks"){
|
||||||
|
node.WaitForContent();
|
||||||
|
|
||||||
|
typedef std::vector<std::string> StringVector;
|
||||||
|
StringVector values;
|
||||||
|
|
||||||
|
try{ // lexical_cast can throw
|
||||||
|
boost::algorithm::split(values,node.Content(),boost::algorithm::is_any_of(","));
|
||||||
|
for(StringVector::iterator value=values.begin();value!=values.end();++value){
|
||||||
|
this->tracksToSort.push_back( boost::lexical_cast<DBINT>(*value) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(...){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
this->RecieveQueryStandardNodes(node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Query::SortTracks::Name(){
|
||||||
|
return "SortTracks";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Query::SortTracks::SendQuery(musik::core::xml::WriterNode &queryNode){
|
||||||
|
{
|
||||||
|
xml::WriterNode tracksNode(queryNode,"tracks");
|
||||||
|
|
||||||
|
for(IntVector::iterator trackId=this->tracksToSort.begin();trackId!=this->tracksToSort.end();++trackId){
|
||||||
|
if(!tracksNode.Content().empty()){
|
||||||
|
tracksNode.Content().append(",");
|
||||||
|
}
|
||||||
|
tracksNode.Content().append(boost::lexical_cast<std::string>(*trackId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->SendQueryStandardNodes(queryNode);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -46,14 +46,7 @@
|
|||||||
#include <core/Query/ListBase.h>
|
#include <core/Query/ListBase.h>
|
||||||
#include <core/tracklist/IRandomAccess.h>
|
#include <core/tracklist/IRandomAccess.h>
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
// Forward declarations
|
|
||||||
//////////////////////////////////////////////////////////////
|
|
||||||
namespace musik{ namespace core{
|
|
||||||
namespace Library{
|
|
||||||
class Base;
|
|
||||||
}
|
|
||||||
} }
|
|
||||||
|
|
||||||
|
|
||||||
namespace musik{ namespace core{
|
namespace musik{ namespace core{
|
||||||
@ -74,17 +67,22 @@ namespace musik{ namespace core{
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
std::vector<int> tracksToSort;
|
typedef std::vector<int> IntVector;
|
||||||
|
IntVector tracksToSort;
|
||||||
std::list<std::string> sortMetaKeys;
|
std::list<std::string> sortMetaKeys;
|
||||||
|
|
||||||
|
|
||||||
friend class Library::Base;
|
friend class Library::Base;
|
||||||
friend class Library::LocalDB;
|
friend class Library::LocalDB;
|
||||||
|
|
||||||
virtual bool ParseQuery(Library::Base *library,db::Connection &db);
|
|
||||||
|
|
||||||
Ptr copy() const;
|
Ptr copy() const;
|
||||||
|
|
||||||
|
virtual std::string Name();
|
||||||
|
virtual bool ParseQuery(Library::Base *library,db::Connection &db);
|
||||||
|
virtual bool RecieveQuery(musik::core::xml::ParserNode &queryNode);
|
||||||
|
virtual bool SendQuery(musik::core::xml::WriterNode &queryNode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -36,8 +36,10 @@
|
|||||||
|
|
||||||
#include "pch.hpp"
|
#include "pch.hpp"
|
||||||
|
|
||||||
|
#include <core/Common.h>
|
||||||
#include <core/Query/TrackMetadata.h>
|
#include <core/Query/TrackMetadata.h>
|
||||||
#include <core/Library/Base.h>
|
#include <core/Library/Base.h>
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
|
||||||
using namespace musik::core;
|
using namespace musik::core;
|
||||||
using namespace musik::core::Query;
|
using namespace musik::core::Query;
|
||||||
@ -243,7 +245,7 @@ bool TrackMetadata::RunCallbacks(Library::Base *library){
|
|||||||
|
|
||||||
// First swap the results so that Query can continue to parse
|
// First swap the results so that Query can continue to parse
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock oLock(library->oResultMutex);
|
boost::mutex::scoped_lock lock(library->oResultMutex);
|
||||||
aResultCopy.swap(this->aResultTracks);
|
aResultCopy.swap(this->aResultTracks);
|
||||||
|
|
||||||
if( (this->status & Status::Ended)!=0){
|
if( (this->status & Status::Ended)!=0){
|
||||||
@ -288,7 +290,9 @@ void TrackMetadata::RequestAllMetakeys(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
Query::Ptr TrackMetadata::copy() const{
|
Query::Ptr TrackMetadata::copy() const{
|
||||||
return Query::Ptr(new Query::TrackMetadata(*this));
|
Query::Ptr queryCopy(new Query::TrackMetadata(*this));
|
||||||
|
queryCopy->PostCopy();
|
||||||
|
return queryCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TrackMetadata::PreAddQuery(Library::Base *library){
|
void TrackMetadata::PreAddQuery(Library::Base *library){
|
||||||
@ -297,4 +301,170 @@ void TrackMetadata::PreAddQuery(Library::Base *library){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string TrackMetadata::Name(){
|
||||||
|
return "TrackMetadata";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TrackMetadata::RecieveQuery(musik::core::xml::ParserNode &queryNode){
|
||||||
|
|
||||||
|
while(musik::core::xml::ParserNode metakeysNode = queryNode.ChildNode()){
|
||||||
|
if(metakeysNode.Name()=="metakeys"){
|
||||||
|
if(metakeysNode.Attributes()["all"]=="true"){
|
||||||
|
this->RequestAllMetakeys();
|
||||||
|
}else{
|
||||||
|
metakeysNode.WaitForContent();
|
||||||
|
|
||||||
|
StringSet values;
|
||||||
|
|
||||||
|
try{ // lexical_cast can throw
|
||||||
|
boost::algorithm::split(values,metakeysNode.Content(),boost::algorithm::is_any_of(","));
|
||||||
|
this->RequestMetakeys(values);
|
||||||
|
}
|
||||||
|
catch(...){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else if(metakeysNode.Name()=="tracks"){
|
||||||
|
metakeysNode.WaitForContent();
|
||||||
|
|
||||||
|
typedef std::vector<std::string> StringVector;
|
||||||
|
StringVector values;
|
||||||
|
try{ // lexical_cast can throw
|
||||||
|
boost::algorithm::split(values,metakeysNode.Content(),boost::algorithm::is_any_of(","));
|
||||||
|
for(StringVector::iterator value=values.begin();value!=values.end();++value){
|
||||||
|
this->RequestTrack(TrackPtr(new Track( boost::lexical_cast<DBINT>(*value) )));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(...){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TrackMetadata::SendQuery(musik::core::xml::WriterNode &queryNode){
|
||||||
|
{
|
||||||
|
musik::core::xml::WriterNode metakeysNode(queryNode,"metakeys");
|
||||||
|
if(this->requestAllFields){
|
||||||
|
metakeysNode.Attributes()["all"] = "true";
|
||||||
|
}else{
|
||||||
|
for(StringSet::iterator metakey=this->requestedFields.begin();metakey!=this->requestedFields.end();++metakey){
|
||||||
|
if(!metakeysNode.Content().empty()){
|
||||||
|
metakeysNode.Content().append(",");
|
||||||
|
}
|
||||||
|
metakeysNode.Content().append(*metakey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
musik::core::xml::WriterNode tracksNode(queryNode,"tracks");
|
||||||
|
|
||||||
|
for(TrackVector::iterator track=this->aRequestTracks.begin();track!=this->aRequestTracks.end();++track){
|
||||||
|
if(!tracksNode.Content().empty()){
|
||||||
|
tracksNode.Content().append(",");
|
||||||
|
}
|
||||||
|
tracksNode.Content().append( boost::lexical_cast<std::string>( (*track)->id ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TrackMetadata::SendResults(musik::core::xml::WriterNode &queryNode,Library::Base *library){
|
||||||
|
|
||||||
|
bool continueSending(true);
|
||||||
|
|
||||||
|
while(continueSending){
|
||||||
|
TrackVector resultCopy;
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock lock(library->oResultMutex);
|
||||||
|
resultCopy.swap(this->aResultTracks);
|
||||||
|
|
||||||
|
if( (this->status & Status::Ended)!=0){
|
||||||
|
continueSending = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the results
|
||||||
|
if( !resultCopy.empty() ){
|
||||||
|
try{
|
||||||
|
for(TrackVector::iterator track=resultCopy.begin();track!=resultCopy.end();++track){
|
||||||
|
musik::core::xml::WriterNode trackNode(queryNode,"t");
|
||||||
|
trackNode.Attributes()["id"] = boost::lexical_cast<std::string>( (*track)->id );
|
||||||
|
|
||||||
|
TrackMeta::TagMapIteratorPair metaDatas( (*track)->GetAllValues() );
|
||||||
|
for(TrackMeta::TagMapConstIterator metaData=metaDatas.first;metaData!=metaDatas.second;++metaData){
|
||||||
|
musik::core::xml::WriterNode metaDataNode(trackNode,"md");
|
||||||
|
metaDataNode.Attributes()["k"] = metaData->first;
|
||||||
|
metaDataNode.Content().append( ConvertUTF8(metaData->second) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(...){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for more results
|
||||||
|
if( continueSending && resultCopy.empty()){
|
||||||
|
boost::thread::yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TrackMetadata::RecieveResults(musik::core::xml::ParserNode &queryNode,Library::Base *library){
|
||||||
|
|
||||||
|
while(musik::core::xml::ParserNode trackNode=queryNode.ChildNode("t") ){
|
||||||
|
try{
|
||||||
|
DBINT trackId( boost::lexical_cast<DBINT>(trackNode.Attributes()["id"]) );
|
||||||
|
|
||||||
|
// Find the track in the aRequestTracks
|
||||||
|
TrackVector::iterator track=this->aRequestTracks.begin();
|
||||||
|
bool trackFound(false);
|
||||||
|
while(track!=this->aRequestTracks.end() && !trackFound){
|
||||||
|
if( (*track)->id==trackId ){
|
||||||
|
// TrackPtr found
|
||||||
|
trackFound = true;
|
||||||
|
}else{
|
||||||
|
++track;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(track!=this->aRequestTracks.end() && trackFound){
|
||||||
|
TrackPtr currentTrack(*track);
|
||||||
|
|
||||||
|
// Remove the track from the aRequestTracks
|
||||||
|
this->aRequestTracks.erase(track);
|
||||||
|
|
||||||
|
// Get the metadata
|
||||||
|
while(musik::core::xml::ParserNode metadataNode=trackNode.ChildNode("md") ){
|
||||||
|
metadataNode.WaitForContent();
|
||||||
|
currentTrack->SetValue( metadataNode.Attributes()["k"].c_str(),ConvertUTF16(metadataNode.Content()).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock oLock(library->oResultMutex);
|
||||||
|
this->aResultTracks.push_back(currentTrack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(...){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -72,10 +72,11 @@ class TrackMetadata : public Query::Base {
|
|||||||
TrackMetadataEvent OnTracksEvent;
|
TrackMetadataEvent OnTracksEvent;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::set<std::string> requestedFields;
|
typedef std::set<std::string> StringSet;
|
||||||
|
StringSet requestedFields;
|
||||||
std::vector<std::string> fieldOrder;
|
std::vector<std::string> fieldOrder;
|
||||||
std::set<std::string> metaFields;
|
StringSet metaFields;
|
||||||
std::set<std::string> categoryFields;
|
StringSet categoryFields;
|
||||||
std::string sSQL;
|
std::string sSQL;
|
||||||
std::string sSQLTables;
|
std::string sSQLTables;
|
||||||
std::string sSQLWhere;
|
std::string sSQLWhere;
|
||||||
@ -89,9 +90,17 @@ class TrackMetadata : public Query::Base {
|
|||||||
protected:
|
protected:
|
||||||
friend class Library::Base;
|
friend class Library::Base;
|
||||||
friend class Library::LocalDB;
|
friend class Library::LocalDB;
|
||||||
bool ParseQuery(Library::Base *library,db::Connection &db);
|
|
||||||
Ptr copy() const;
|
Ptr copy() const;
|
||||||
void PreAddQuery(Library::Base *library);
|
void PreAddQuery(Library::Base *library);
|
||||||
|
|
||||||
|
virtual bool ParseQuery(Library::Base *library,db::Connection &db);
|
||||||
|
|
||||||
|
virtual std::string Name();
|
||||||
|
virtual bool RecieveQuery(musik::core::xml::ParserNode &queryNode);
|
||||||
|
virtual bool SendQuery(musik::core::xml::WriterNode &queryNode);
|
||||||
|
virtual bool SendResults(musik::core::xml::WriterNode &queryNode,Library::Base *library);
|
||||||
|
virtual bool RecieveResults(musik::core::xml::ParserNode &queryNode,Library::Base *library);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -154,8 +154,8 @@ bool Track::CompareDBAndFileInfo(const boost::filesystem::utfpath &file,db::Conn
|
|||||||
this->SetValue("extension",file.leaf().substr(lastDot+1).c_str());
|
this->SetValue("extension",file.leaf().substr(lastDot+1).c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
DBINT fileSize = boost::filesystem::file_size(file);
|
DBINT fileSize = (DBINT)boost::filesystem::file_size(file);
|
||||||
DBTIME fileTime = boost::filesystem::last_write_time(file);
|
DBTIME fileTime = (DBTIME)boost::filesystem::last_write_time(file);
|
||||||
|
|
||||||
this->SetValue("filesize",boost::lexical_cast<utfstring>(fileSize).c_str());
|
this->SetValue("filesize",boost::lexical_cast<utfstring>(fileSize).c_str());
|
||||||
this->SetValue("filetime",boost::lexical_cast<utfstring>(fileTime).c_str());
|
this->SetValue("filetime",boost::lexical_cast<utfstring>(fileTime).c_str());
|
||||||
|
@ -105,12 +105,20 @@ void Connection::ReadThread(){
|
|||||||
if(queryIt!=queryMap.end()){
|
if(queryIt!=queryMap.end()){
|
||||||
// Query type exists, lets create a copy
|
// Query type exists, lets create a copy
|
||||||
musik::core::Query::Ptr query( queryIt->second->copy() );
|
musik::core::Query::Ptr query( queryIt->second->copy() );
|
||||||
query->queryId = boost::lexical_cast<unsigned int>(queryNode.Attributes()["id"]);
|
try{
|
||||||
|
query->queryId = boost::lexical_cast<unsigned int>(queryNode.Attributes()["id"]);
|
||||||
|
query->uniqueId = boost::lexical_cast<unsigned int>(queryNode.Attributes()["uid"]);
|
||||||
|
}catch(...){}
|
||||||
|
|
||||||
if(query->RecieveQuery(queryNode)){
|
if(query->RecieveQuery(queryNode)){
|
||||||
|
|
||||||
|
unsigned int options(0);
|
||||||
|
try{
|
||||||
|
options = boost::lexical_cast<unsigned int>(queryNode.Attributes()["options"]);
|
||||||
|
}catch(...){}
|
||||||
|
|
||||||
// TODO: check for AddQuery options in tag
|
// TODO: check for AddQuery options in tag
|
||||||
this->AddQuery( *query,boost::lexical_cast<unsigned int>(queryNode.Attributes()["options"]) );
|
this->AddQuery( *query,options|musik::core::Query::CopyUniqueId );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,6 +221,7 @@ void Connection::WriteThread(){
|
|||||||
musik::core::xml::WriterNode queryNode(musikNode,"queryresults");
|
musik::core::xml::WriterNode queryNode(musikNode,"queryresults");
|
||||||
queryNode.Attributes()["type"] = sendQuery->Name();
|
queryNode.Attributes()["type"] = sendQuery->Name();
|
||||||
queryNode.Attributes()["id"] = boost::lexical_cast<std::string>(sendQuery->queryId);
|
queryNode.Attributes()["id"] = boost::lexical_cast<std::string>(sendQuery->queryId);
|
||||||
|
queryNode.Attributes()["uid"] = boost::lexical_cast<std::string>(sendQuery->uniqueId);
|
||||||
|
|
||||||
sendQuery->SendResults(queryNode,this);
|
sendQuery->SendResults(queryNode,this);
|
||||||
}
|
}
|
||||||
|
@ -148,20 +148,22 @@ void Standard::OnTracksFromQuery(musik::core::TrackVector *newTracks,bool clear)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Standard::LoadTrack(int position){
|
void Standard::LoadTrack(int position){
|
||||||
|
|
||||||
int trackCount(0);
|
|
||||||
|
|
||||||
for(int i(position);i<position+this->hintedRows;++i){
|
if(this->QueryForTrack(position)){
|
||||||
if(this->QueryForTrack(i)){
|
|
||||||
++trackCount;
|
int trackCount(1);
|
||||||
|
|
||||||
|
for(int i(position+1);i<position+this->hintedRows;++i){
|
||||||
|
if(this->QueryForTrack(i)){
|
||||||
|
++trackCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(trackCount && this->library){
|
||||||
|
this->library->AddQuery(this->trackQuery,musik::core::Query::Prioritize);
|
||||||
|
this->trackQuery.Clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(trackCount && this->library){
|
|
||||||
this->library->AddQuery(this->trackQuery,musik::core::Query::Prioritize);
|
|
||||||
this->trackQuery.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Standard::QueryForTrack(int position){
|
bool Standard::QueryForTrack(int position){
|
||||||
|
@ -38,6 +38,8 @@
|
|||||||
#include <core/xml/ParserNode.h>
|
#include <core/xml/ParserNode.h>
|
||||||
#include <expat/expat.h>
|
#include <expat/expat.h>
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
using namespace musik::core::xml;
|
using namespace musik::core::xml;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
@ -157,6 +159,11 @@ void Parser::ReadFromSocket(){
|
|||||||
this->Exit();
|
this->Exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Log
|
||||||
|
// std::ofstream logFile("mc2_Parser.log",std::ios::app);
|
||||||
|
// logFile.write(this->readBuffer.c_array(),this->readBufferLength);
|
||||||
|
// logFile << std::endl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#include <core/xml/Writer.h>
|
#include <core/xml/Writer.h>
|
||||||
#include <core/xml/WriterNode.h>
|
#include <core/xml/WriterNode.h>
|
||||||
#include <boost/algorithm/string/replace.hpp>
|
#include <boost/algorithm/string/replace.hpp>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
using namespace musik::core::xml;
|
using namespace musik::core::xml;
|
||||||
|
|
||||||
@ -175,9 +176,16 @@ void Writer::Send(){
|
|||||||
// Time to send the buffer
|
// Time to send the buffer
|
||||||
if(!sendBuffer.empty()){
|
if(!sendBuffer.empty()){
|
||||||
boost::asio::write(*(this->socket),boost::asio::buffer(sendBuffer));
|
boost::asio::write(*(this->socket),boost::asio::buffer(sendBuffer));
|
||||||
|
// Log
|
||||||
|
//std::ofstream logFile("mc2_Writer.log",std::ios::app);
|
||||||
|
//logFile << sendBuffer << std::endl;
|
||||||
|
|
||||||
sendBuffer.clear();
|
sendBuffer.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch(boost::system::error_code &error){
|
||||||
|
this->Exit();
|
||||||
|
}
|
||||||
catch(...){
|
catch(...){
|
||||||
this->Exit();
|
this->Exit();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user