Permalink
Browse files

move /api/ to a plugin

  • Loading branch information...
1 parent 04d58e3 commit f312911bc043fc210efbf17a6854b98e704237d9 @RJ committed May 5, 2009
View
@@ -72,7 +72,7 @@ ADD_EXECUTABLE( playdar
${SRC}/rs_script.cpp
${SRC}/utils/uuid.cpp
- ${SRC}/utils/base64.cpp
+# ${SRC}/utils/base64.cpp
${SRC}/utils/levenshtein.cpp
${SRC}/playdar_request_handler.cpp
@@ -22,7 +22,7 @@ class PluginAdaptor
// A short name used eg in url handler
virtual std::string classname() const = 0;
-
+ virtual std::string playdar_version() const = 0;
virtual void set(const std::string& key, json_spirit::Value value) = 0;
virtual json_spirit::Value getstring(const std::string& key, const std::string& def) const = 0;
virtual json_spirit::Value getint(const std::string& key, const int def) const = 0;
@@ -38,7 +38,12 @@ class PluginAdaptor
{ m_rs = rs; }
virtual bool query_exists(const query_uid & qid) = 0;
-
+
+ virtual std::vector< ri_ptr > get_results(query_uid qid) = 0;
+ virtual int num_results(query_uid qid) = 0;
+ virtual rq_ptr rq(const query_uid & qid) = 0;
+ virtual void cancel_query(const query_uid & qid) = 0;
+
virtual ResolverService * rs() const { return m_rs; }
virtual const std::string hostname() const = 0;
@@ -33,6 +33,11 @@ class PluginAdaptorImpl : public PluginAdaptor
{
}
+ virtual std::string playdar_version() const
+ {
+ return VERSION;
+ }
+
virtual void set(const std::string& key, json_spirit::Value value)
{
// TODO
@@ -100,6 +105,26 @@ class PluginAdaptorImpl : public PluginAdaptor
{
return m_resolver->query_exists(qid);
}
+
+ virtual std::vector< ri_ptr > get_results(query_uid qid)
+ {
+ return m_resolver->get_results(qid);
+ }
+
+ virtual rq_ptr rq(const query_uid & qid)
+ {
+ return m_resolver->rq(qid);
+ }
+
+ virtual int num_results(query_uid qid)
+ {
+ return m_resolver->num_results(qid);
+ }
+
+ virtual void cancel_query(const query_uid & qid)
+ {
+ m_resolver->cancel_query(qid);
+ }
virtual query_uid dispatch(boost::shared_ptr<ResolverQuery> rq)
{
View
@@ -180,10 +180,10 @@
<used>false</used>
<version>3</version>
<includestyle>3</includestyle>
- <root></root>
+ <root>/usr/share/qt3</root>
<designerintegration>EmbeddedKDevDesigner</designerintegration>
- <qmake></qmake>
- <designer></designer>
+ <qmake>/usr/bin/qmake-qt3</qmake>
+ <designer>/usr/bin/designer</designer>
<designerpluginpaths/>
</qt>
<codecompletion>
@@ -0,0 +1,15 @@
+ADD_LIBRARY( api SHARED
+ api.cpp
+ )
+
+# Ensure the shared library file is called <CLASS NAME>.resolver
+# Playdar looks for a class with the same name as the file, minus suffix
+#
+SET_TARGET_PROPERTIES( api PROPERTIES
+ PREFIX ""
+ SUFFIX ".resolver" )
+
+TARGET_LINK_LIBRARIES( api
+ ${PLAYDAR_PLUGIN_LDFLAGS}
+ ${Boost_LIBRARIES}
+ )
View
@@ -0,0 +1,150 @@
+#include "api.h"
+#include <boost/algorithm/string.hpp>
+#include "playdar/playdar_request.h"
+#include "playdar/track_rq_builder.hpp"
+
+namespace playdar {
+namespace resolvers {
+
+using namespace std;
+
+bool
+api::init( pa_ptr pap )
+{
+ m_pap = pap;
+ return true;
+}
+
+playdar_response
+api::anon_http_handler(const playdar_request* req)
+{
+ using namespace json_spirit;
+ ostringstream response;
+ if(req->getvar("method") == "stat") {
+ Object r;
+ r.push_back( Pair("name", "playdar") );
+ r.push_back( Pair("version", m_pap->playdar_version()) );
+ r.push_back( Pair("authenticated", false) );
+ write_formatted( r, response );
+ }
+ playdar_response r(response.str(), false);
+ return r;
+}
+
+playdar_response
+api::authed_http_handler(const playdar_request* req, playdar::auth* pauth)
+{
+ using namespace json_spirit;
+
+ ostringstream response;
+ do
+ {
+ if(req->getvar("method") == "stat")
+ {
+ Object r;
+ r.push_back( Pair("name", "playdar") );
+ r.push_back( Pair("version", m_pap->playdar_version()) );
+ r.push_back( Pair("authenticated", true) );
+
+ r.push_back( Pair("hostname", m_pap->hostname()) );
+ //r.push_back( Pair("permissions", permissions) );
+ //r.push_back( Pair("capabilities", "TODO") ); // might do something clever here later
+ write_formatted( r, response );
+ break;
+ }
+
+ if(req->getvar("method") == "resolve")
+ {
+ string artist = req->getvar_exists("artist") ? req->getvar("artist") : "";
+ string album = req->getvar_exists("album") ? req->getvar("album") : "";
+ string track = req->getvar_exists("track") ? req->getvar("track") : "";
+ // create a new query and start resolving it:
+ boost::shared_ptr<ResolverQuery> rq = TrackRQBuilder::build(artist, album, track);
+
+ // was a QID specified? if so, use it:
+ if(req->getvar_exists("qid"))
+ {
+ if( !m_pap->query_exists(req->getvar("qid")) )
+ {
+ rq->set_id(req->getvar("qid"));
+ }
+ else
+ {
+ cout << "WARNING - resolve request provided a QID, but that QID already exists as a running query. Assigning a new QID." << endl;
+ // new qid assigned automatically if we don't provide one.
+ }
+ }
+ if( !TrackRQBuilder::valid(rq) ) // usually caused by empty track name or something.
+ {
+ cout << "Tried to dispatch an invalid query, failing." << endl;
+ playdar_response r("");
+ r.set_response_code( 400 ); // bad_request
+ return r;
+ }
+ rq->set_from_name(m_pap->hostname());
+ query_uid qid = m_pap->dispatch(rq);
+ Object r;
+ r.push_back( Pair("qid", qid) );
+ write_formatted( r, response );
+ }
+ else if(req->getvar("method") == "cancel")
+ {
+ query_uid qid = req->getvar("qid");
+ m_pap->cancel_query(qid);
+ // return something.. typically not checked, but easier to debug like this:
+ response << "{ \"status\" : \"OK\" }";
+ }
+ else if(req->getvar("method") =="get_results" && req->getvar_exists("qid"))
+ {
+ if( !m_pap->query_exists( req->getvar("qid") ) )
+ {
+ cerr << "Error get_results(" << req->getvar("qid") << ") - qid went away." << endl;
+ playdar_response r("");
+ r.set_response_code( 404 ); // bad_request
+ return r;
+ }
+ Object r;
+ Array qresults;
+ vector< ri_ptr > results = m_pap->get_results(req->getvar("qid"));
+ BOOST_FOREACH(ri_ptr rip, results)
+ {
+ qresults.push_back( rip->get_json());
+ }
+ r.push_back( Pair("qid", req->getvar("qid")) );
+ r.push_back( Pair("refresh_interval", 1000) ); //TODO something better?
+ r.push_back( Pair("query", m_pap->rq(req->getvar("qid"))->get_json()) );
+ r.push_back( Pair("results", qresults) );
+
+ write_formatted( r, response );
+ }
+ else
+ {
+ response << "FAIL";
+ }
+
+ }while(false);
+
+ // wrap the JSON response in the javascript callback code:
+ string retval;
+ if(req->getvar_exists("jsonp")) // wrap in js callback
+ {
+ retval = req->getvar("jsonp");
+ retval += "(" ;
+ string s = response.str();
+ //while((pos = s.find("\n"))!=string::npos) s.erase(pos,1);
+ retval += s + ");\n";
+ }
+ else
+ {
+ retval = response.str();
+ }
+ playdar_response r(retval, false);
+ r.add_header( "Content-Type", req->getvar_exists("jsonp") ?
+ "text/javascript; charset=utf-8" :
+ "text/plain; charset=utf-8" );
+ return r;
+}
+
+
+} // resolvers
+} // playdar
View
@@ -0,0 +1,36 @@
+#ifndef __RS_API_H__
+#define __RS_API_H__
+// All resolver plugins should include this header:
+#include "playdar/playdar_plugin_include.h"
+
+namespace playdar {
+namespace resolvers {
+
+class api : public ResolverPlugin<api>
+{
+public:
+ api() {}
+
+ bool init( pa_ptr );
+ void start_resolving(boost::shared_ptr<ResolverQuery> rq) {} //noop
+ unsigned short weight() const { return 0; }
+ unsigned short targettime() const { return 0; }
+ std::string name() const { return "api"; }
+
+ // all we really do is handle http requests:
+ playdar_response anon_http_handler(const playdar_request*);
+ playdar_response authed_http_handler(const playdar_request*, playdar::auth* pauth);
+
+protected:
+ virtual ~api() throw() {}
+
+private:
+ pa_ptr m_pap;
+};
+
+// This makes the plugin loading possible:
+EXPORT_DYNAMIC_CLASS( api )
+
+} // resolvers
+} // playdar
+#endif
View
@@ -154,7 +154,8 @@ int main(int ac, char *av[])
return error ? 1 : 0;
}
if (vm.count("version")) {
- cout << VERSION << endl;
+ cout << VERSION << endl
+ << "Compiled: " << __DATE__ << " " << __TIME__ << endl;
return 0;
}
Oops, something went wrong.

0 comments on commit f312911

Please sign in to comment.