Permalink
Browse files

minor refactoring, lan/udp resolver implemented as process too

  • Loading branch information...
RJ committed Apr 1, 2009
1 parent b3898d4 commit faf3e891f0c93bfca93a3c3250c36ea78881513f
View
@@ -72,7 +72,7 @@ function get_matches($rq){
// settings for this resolver, reported when we start:
function get_settings(){
$s = new stdclass;
- $s->settings = true;
+ $s->_msgtype = "settings";
$s->name = "php resolver script";
$s->targettime = 15; // fast atm, it's all hardcoded.
$s->weight = 80; // 1-100. higher means preferable.
View
@@ -72,7 +72,7 @@ def resolve(artist, track):
####################################################################### settings
settings = dict()
-settings["settings"] = True
+settings["_msgtype"] = "settings"
settings["name"] = "SeeqPod Resolver (Python 2.6)"
settings["targettime"] = 1000 # millseconds
settings["weight"] = 50 # seeqpod results aren't as good as friend's results
@@ -3,6 +3,7 @@
#include "playdar/config.hpp"
#include "playdar/streaming_strategy.h"
#include "playdar/types.h"
+#include "playdar/ss_http.hpp"
#include "json_spirit/json_spirit.h"
#include <cassert>
/*
@@ -34,7 +35,6 @@ class PlayableItem
set_mimetype("text/plain");
set_preference(1.0);
set_source("unspecified");
- //set_url("NO_URL");
}
~PlayableItem()
@@ -44,7 +44,7 @@ class PlayableItem
static boost::shared_ptr<PlayableItem> from_json(json_spirit::Object resobj)
{
- string artist, album, track, sid, source, mimetype;
+ string artist, album, track, sid, source, mimetype, url;
int size, bitrate, duration = 0;
float score = 0;
@@ -64,6 +64,9 @@ class PlayableItem
if(resobj_map.find("sid")!=resobj_map.end())
sid = resobj_map["sid"].get_str();
+ if(resobj_map.find("url")!=resobj_map.end())
+ url = resobj_map["url"].get_str();
+
if(resobj_map.find("source")!=resobj_map.end())
source = resobj_map["source"].get_str();
@@ -103,6 +106,7 @@ class PlayableItem
if(bitrate) pip->set_bitrate(bitrate);
if(duration) pip->set_duration(duration);
if(score) pip->set_score(score);
+ if(url.length()) pip->set_url(url);
return pip;
}
@@ -120,7 +124,7 @@ class PlayableItem
j.push_back( Pair("mimetype", mimetype()) );
j.push_back( Pair("bitrate", bitrate()) );
j.push_back( Pair("duration", duration()) );
- //j.push_back( Pair("url", sid_to_url(id())) );
+ j.push_back( Pair("url", url()) );
j.push_back( Pair("score", (double)score()) );
j.push_back( Pair("preference", (double)preference()) );
return j;
@@ -141,7 +145,7 @@ class PlayableItem
void set_artist(string s) { m_artist = s; }
void set_album(string s) { m_album = s; }
void set_track(string s) { m_track = s; }
- //void set_url(string s) { m_url = s; }
+ void set_url(string s) { m_url = s; }
void set_source(string s) { m_source = s; }
void set_mimetype(string s) { m_mimetype = s; }
void set_duration(int s) { m_duration = s; }
@@ -162,7 +166,17 @@ class PlayableItem
}
// getters
- boost::shared_ptr<StreamingStrategy> streaming_strategy() const { return m_ss; }
+ boost::shared_ptr<StreamingStrategy> streaming_strategy() const
+ {
+ // TODO (make this mutable and call set_ss on first call?)
+ if(m_ss) return m_ss;
+ if(!m_ss && m_url.length())
+ {
+ return boost::shared_ptr<StreamingStrategy>
+ (new HTTPStreamingStrategy(m_url));
+ }
+ return m_ss; // would be null if not given.
+ }
void set_id(string s) { m_uuid = s; }
@@ -171,6 +185,7 @@ class PlayableItem
const string & track() const { return m_track; }
const string & source() const { return m_source; }
const string & mimetype() const { return m_mimetype; }
+ const string & url() const { return m_url; }
const float score() const { return m_score; }
const int duration() const { return m_duration; }
const int bitrate() const { return m_bitrate; }
@@ -185,6 +200,7 @@ class PlayableItem
string m_album;
string m_track;
string m_mimetype;
+ string m_url;
int m_size;
int m_duration;
int m_bitrate;
@@ -0,0 +1,91 @@
+/*
+ This header is a helper for any external resolver written in c++
+ It handles communicating with playdar over stdio.
+*/
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+#include <boost/foreach.hpp>
+#include <boost/asio.hpp>
+#include <boost/thread.hpp>
+#include <stdio.h>
+#include <iostream>
+#include <map>
+#include <string>
+
+#include "json_spirit/json_spirit.h"
+#include "playdar/resolver_query.hpp"
+#include "playdar/playable_item.hpp"
+
+#define MAXBUF 4096 // max size of msg payload
+
+using namespace std;
+using namespace json_spirit;
+
+set< query_uid > dispatched_qids; // qids we already searched for.
+
+// send a msg back to playdar app
+// it takes a JSON val, and prepends the frame (4 byte length indicator)
+void playdar_write( Value v )
+{
+ ostringstream os;
+ write_formatted( v, os );
+ string msg = os.str();
+ boost::uint32_t len = htonl(msg.length());
+ cout.write( (char*)&len, 4 );
+ cout.write( msg.data(), msg.length() );
+ cout.flush();
+}
+
+// ask if we should dispatch this query (checks if we've already seen it etc)
+bool playdar_should_dispatch( query_uid qid )
+{
+ if(dispatched_qids.find(qid)!=dispatched_qids.end())
+ {
+ //cerr << "Skipping dispatch, already seen qid " << rq->id() << endl;
+ return false;
+ }else{
+ dispatched_qids.insert( qid );
+ return true;
+ }
+}
+
+// tell playdar to start resolving this query
+void playdar_dispatch( rq_ptr rq )
+{
+ Object o;
+ o.push_back( Pair("_msgtype", "query") );
+ o.push_back( Pair("query", rq->get_json()) );
+ playdar_write( o );
+}
+
+
+// tell playdar we found a result for something
+void playdar_report_results( query_uid qid, vector< pi_ptr > results )
+{
+ cerr << "Reporting results (not) " << endl;
+ Object o;
+ o.push_back( Pair("_msgtype", "results") );
+ o.push_back( Pair("qid", qid) );
+ Array arr;
+ BOOST_FOREACH( pi_ptr pip, results )
+ {
+ arr.push_back( pip->get_json() );
+ }
+ o.push_back( Pair("results", arr) );
+ playdar_write( o );
+}
+
+// report settings about this resolver
+void playdar_send_settings( const string& name, int weight, int targettime )
+{
+ Object o;
+ o.push_back( Pair("_msgtype", "settings") );
+ o.push_back( Pair("name", name) );
+ o.push_back( Pair("weight", weight) );
+ o.push_back( Pair("targettime", targettime) );
+ playdar_write( o );
+}
+
+
+
+
@@ -58,12 +58,14 @@ class rs_script : public ResolverService
void init_worker();
void process_output();
+ void process_stderr();
bool m_dead;
bool m_got_settings;
string m_scriptpath;
bp::child * m_c;
- boost::thread * m_t;
+ boost::thread * m_t; // std out (main comms)
+ boost::thread * m_e; // std error (logging)
bp::postream * m_os;
bool m_exiting;
@@ -1,7 +1,7 @@
#ifndef __HTTP_STRAT_H__
#define __HTTP_STRAT_H__
#include <boost/asio.hpp>
-
+#include "playdar/streaming_strategy.h"
using namespace boost::asio::ip;
/*
Consider this a nasty hack until I find a decent c++ http library
@@ -0,0 +1,45 @@
+PROJECT(lanresolver)
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6 FATAL_ERROR)
+
+SET(PLAYDAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../")
+SET(CMAKE_MODULE_PATH "${PLAYDAR_PATH}/CMakeModules")
+SET(DEPS "${PLAYDAR_PATH}/deps")
+
+FIND_PACKAGE(Boost 1.35 REQUIRED COMPONENTS filesystem system regex thread program_options)
+FIND_PACKAGE(OsspUuid REQUIRED)
+
+INCLUDE_DIRECTORIES(
+ ${DEPS}/json_spirit_v3.00 # json parser, using boost spirit
+ ${PLAYDAR_PATH}/includes # playdar includes
+ ${OSSPUUID_INCLUDE_DIR}
+ ${Boost_INCLUDE_DIR}
+ /usr/local/include
+ )
+
+# Always check local/lib first:
+LINK_DIRECTORIES(/usr/local/lib)
+
+SET(CMAKE_VERBOSE_MAKEFILE ON)
+INCLUDE(InstallRequiredSystemLibraries)
+
+#add definitions, compiler switches, etc.
+ADD_DEFINITIONS(-Wall -ggdb)
+
+# PDL doesn't know apple mac = posix, this tells it:
+IF(APPLE)
+ ADD_DEFINITIONS(-Dunix)
+ENDIF(APPLE)
+
+ADD_EXECUTABLE(lanresolver
+ main.cpp
+ # json parser:
+ ${DEPS}/json_spirit_v3.00/json_spirit/json_spirit_reader.cpp
+ ${DEPS}/json_spirit_v3.00/json_spirit/json_spirit_value.cpp
+ ${DEPS}/json_spirit_v3.00/json_spirit/json_spirit_writer.cpp
+ )
+TARGET_LINK_LIBRARIES(lanresolver
+ ${OSSPUUID_LIBRARIES} # BSD-like
+ ${Boost_SYSTEM_LIBRARY}
+ ${Boost_THREAD_LIBRARY}
+ )
+
@@ -0,0 +1,3 @@
+Took the lan/udp resolver and moved it into an external process:
+Broadcasts searches on the LAN using UDP multicast.
+Streams results using normal HTTP requests.
Oops, something went wrong.

0 comments on commit faf3e89

Please sign in to comment.