Permalink
Browse files

Splitting objects.

  • Loading branch information...
residuum committed Sep 25, 2012
1 parent c0c9cda commit 2cee983970690b1287d1ee2db2f8e8a95d133012
Showing with 344 additions and 225 deletions.
  1. +2 −2 Makefile
  2. +8 −2 README.txt
  3. +1 −1 json-decode.c
  4. +1 −1 json-encode.c
  5. +207 −0 oauth.c
  6. +4 −3 purest_json.c
  7. +40 −30 purest_json.h
  8. +14 −0 rest-json.pd
  9. +67 −186 rest-json.c → rest.c
View
@@ -6,11 +6,11 @@ LIBRARY_NAME = purest_json
# add your .c source files, one object per file, to the SOURCES
# variable, help files will be included automatically, and for GUI
# objects, the matching .tcl file too
-SOURCES = rest-json.c json-decode.c json-encode.c urlparams.c
+SOURCES = rest.c oauth.c json-decode.c json-encode.c urlparams.c
# list all pd objects (i.e. myobject.pd) files here, and their helpfiles will
# be included automatically
-PDOBJECTS =
+PDOBJECTS = rest-json.pd
# example patches and related files, in the 'examples' subfolder
EXAMPLES = purest-json-test.pd the-sound-of-money.pd twitter-visualization.pd statistics.pd
View
@@ -29,8 +29,11 @@ package very much a community effort.
Externals in the library
-[rest-json]
-Object for issuing HTTP request. Received data is parsed as JSON data.
+[rest]
+Object for issuing HTTP request.
+
+[oauth]
+Object for issuing GET and POST requests with OAUTH.
[json-encode]
Object for encoding data to JSON.
@@ -41,6 +44,9 @@ Object for decoding JSON data.
[urlparams]
Object for url encoding and contatenating url parameters.
+[rest-json]
+Object for issuing HTTP request. Received data is parsed as JSON data.
+
For the usage of the externals see the help patches for the objects.
View
@@ -6,7 +6,7 @@
static t_class *json_decode_class;
-void setup_json0x2ddecode(void) {
+void json0x2ddecode_setup(void) {
json_decode_class = class_new(gensym("json-decode"), (t_newmethod)json_decode_new,
0, sizeof(t_json_decode), 0, A_GIMME, 0);
class_addsymbol(json_decode_class, (t_method)json_decode_string);
View
@@ -40,7 +40,7 @@ static json_object *create_object(char *value) {
return object;
}
-void setup_json0x2dencode(void) {
+void json0x2dencode_setup(void) {
json_encode_class = class_new(gensym("json-encode"), (t_newmethod)json_encode_new,
(t_method)json_encode_free, sizeof(t_json_encode), 0, A_GIMME, 0);
class_addbang(json_encode_class, (t_method)json_encode_bang);
View
207 oauth.c
@@ -0,0 +1,207 @@
+/*
+ * [oauth] makes RESTful calls to webservices.
+ * */
+
+#include "purest_json.h"
+
+static t_class *oauth_class;
+
+static void *execute_oauth_request(void *thread_args) {
+ t_oauth *x = (t_oauth *)thread_args;
+ char *req_url = NULL;
+ char *postargs = NULL;
+ char *reply = NULL;
+ t_atom http_status_data[3];
+
+ if (strcmp(x->request_type, "POST") == 0) {
+ if (x->parameters) {
+ if (strchr(x->complete_url, '?')) {
+ strcat(x->complete_url, "&");
+ } else {
+ strcat(x->complete_url, "?");
+ }
+ strcat(x->complete_url, x->parameters);
+ }
+ req_url = oauth_sign_url2(x->complete_url, &postargs, OA_HMAC, NULL,
+ x->oauth.client_key, x->oauth.client_secret,
+ x->oauth.token_key, x->oauth.token_secret);
+ reply = oauth_http_post(req_url, postargs);
+ } else {
+ req_url = oauth_sign_url2(x->complete_url, NULL, OA_HMAC, NULL,
+ x->oauth.client_key, x->oauth.client_secret,
+ x->oauth.token_key, x->oauth.token_secret);
+ reply = oauth_http_get(req_url, NULL);
+ }
+ SETSYMBOL(&http_status_data[0], gensym("oauth"));
+
+ if (!reply) {
+ SETSYMBOL(&http_status_data[1], gensym("no reply"));
+ error("Request did not return value");
+ } else {
+ SETSYMBOL(&http_status_data[1], gensym("bang"));
+ outlet_symbol(x->x_ob.ob_outlet, gensym(reply));
+ }
+ outlet_list(x->status_info_outlet, &s_list, 2, &http_status_data[0]);
+ if (postargs) {
+ free(postargs);
+ }
+ if (req_url) {
+ free(req_url);
+ }
+ if (reply) {
+ free(reply);
+ }
+ x->is_data_locked = 0;
+ return NULL;
+}
+
+static void thread_execute(t_oauth *x, void *(*func) (void *)) {
+ int rc;
+ pthread_t thread;
+ pthread_attr_t thread_attributes;
+
+ pthread_attr_init(&thread_attributes);
+ pthread_attr_setdetachstate(&thread_attributes, PTHREAD_CREATE_DETACHED);
+ rc = pthread_create(&thread, &thread_attributes, func, (void *)x);
+ pthread_attr_destroy(&thread_attributes);
+ if (rc) {
+ error("Could not create thread with code %d", rc);
+ x->is_data_locked = 0;
+ }
+}
+
+static void set_url_parameters(t_oauth *x, int argcount, t_atom *argvec) {
+ switch (argcount) {
+ case 3:
+ if (argvec[0].a_type != A_SYMBOL) {
+ error("Base URL cannot be set.");
+ } else {
+ atom_string(argvec, x->base_url, MAXPDSTRING);
+ }
+ if (argvec[1].a_type != A_SYMBOL) {
+ error("Client key cannot be set.");
+ } else {
+ atom_string(argvec + 1, x->oauth.client_key, MAXPDSTRING);
+ }
+ if (argvec[2].a_type != A_SYMBOL) {
+ error("Client secret cannot be set.");
+ } else {
+ atom_string(argvec + 2, x->oauth.client_secret, MAXPDSTRING);
+ }
+ memset(x->oauth.token_key, 0x00, MAXPDSTRING);
+ memset(x->oauth.token_secret, 0x00, MAXPDSTRING);
+ break;
+ case 5:
+ if (argvec[0].a_type != A_SYMBOL) {
+ error("Base URL cannot be set.");
+ } else {
+ atom_string(argvec, x->base_url, MAXPDSTRING);
+ }
+ if (argvec[1].a_type != A_SYMBOL) {
+ error("Client key cannot be set.");
+ } else {
+ atom_string(argvec + 1, x->oauth.client_key, MAXPDSTRING);
+ }
+ if (argvec[2].a_type != A_SYMBOL) {
+ error("Client secret cannot be set.");
+ } else {
+ atom_string(argvec + 2, x->oauth.client_secret, MAXPDSTRING);
+ }
+ if (argvec[3].a_type != A_SYMBOL) {
+ error("Token key cannot be set.");
+ } else {
+ atom_string(argvec + 3, x->oauth.token_key, MAXPDSTRING);
+ }
+ if (argvec[4].a_type != A_SYMBOL) {
+ error("Token secret cannot be set.");
+ } else {
+ atom_string(argvec + 4, x->oauth.token_secret, MAXPDSTRING);
+ }
+ break;
+ default:
+ error("Wrong number of parameters.");
+ break;
+ }
+}
+
+void oauth_setup(void) {
+ oauth_class = class_new(gensym("oauth"), (t_newmethod)oauth_new,
+ 0, sizeof(t_oauth), 0, A_GIMME, 0);
+ class_addmethod(oauth_class, (t_method)oauth_url, gensym("url"), A_GIMME, 0);
+ class_addmethod(oauth_class, (t_method)oauth_command, gensym("GET"), A_GIMME, 0);
+ class_addmethod(oauth_class, (t_method)oauth_command, gensym("POST"), A_GIMME, 0);
+}
+
+void oauth_command(t_oauth *x, t_symbol *selector, int argcount, t_atom *argvec) {
+ char *request_type;
+ char path[MAXPDSTRING];
+ char parameters[MAXPDSTRING];
+ char *cleaned_parameters;
+ size_t memsize = 0;
+ t_atom auth_status_data[2];
+
+ if(x->is_data_locked) {
+ post("oauth object is performing request and locked");
+ } else {
+ memset(x->request_type, 0x00, 7);
+ memset(x->parameters, 0x00, MAXPDSTRING);
+ memset(x->complete_url, 0x00, MAXPDSTRING);
+ switch (argcount) {
+ case 0:
+ break;
+ default:
+ request_type = selector->s_name;
+ atom_string(argvec, path, MAXPDSTRING);
+ if (argcount > 1) {
+ atom_string(argvec + 1, parameters, MAXPDSTRING);
+ }
+ x->is_data_locked = 1;
+ if (x->base_url != NULL) {
+ strcpy(x->complete_url, x->base_url);
+ }
+ strcat(x->complete_url, path);
+ strcpy(x->request_type, request_type);
+ if (parameters != NULL) {
+ cleaned_parameters = remove_backslashes(parameters, memsize);
+ strcpy(x->parameters, cleaned_parameters);
+ freebytes(cleaned_parameters, memsize);
+ }
+ if ((strcmp(x->request_type, "GET") &&
+ strcmp(x->request_type, "POST"))) {
+ SETSYMBOL(&auth_status_data[0], gensym("oauth"));
+ SETSYMBOL(&auth_status_data[1], gensym("Request Method not supported"));
+ error("Request method %s not supported.", x->request_type);
+ outlet_list(x->status_info_outlet, &s_list, 2, &auth_status_data[0]);
+ x->is_data_locked = 0;
+ } else {
+ thread_execute(x, execute_oauth_request);
+ }
+ break;
+ }
+ }
+}
+
+void oauth_url(t_oauth *x, t_symbol *selector, int argcount, t_atom *argvec) {
+
+ (void) selector;
+
+ if(x->is_data_locked) {
+ post("oauth object is performing request and locked");
+ } else {
+ set_url_parameters(x, argcount, argvec);
+ }
+}
+
+void *oauth_new(t_symbol *selector, int argcount, t_atom *argvec) {
+ t_oauth *x = (t_oauth *)pd_new(oauth_class);
+
+ (void) selector;
+
+ set_url_parameters(x, argcount, argvec);
+
+ outlet_new(&x->x_ob, NULL);
+ x->status_info_outlet = outlet_new(&x->x_ob, NULL);
+ x->is_data_locked = 0;
+
+ return (void *)x;
+}
View
@@ -4,8 +4,9 @@ void purest_json_setup(void) {
post("PuREST JSON version %s: A library for executing HTTP queries and encoding and decoding JSON data from Puredata.", LIBRARY_VERSION);
post("(c) Thomas Mayer (Residuum) 2012");
post("Get the latest source from https://github.com/residuum/PuRestJson");
- setup_rest0x2djson();
- setup_json0x2dencode();
- setup_json0x2ddecode();
+ rest_setup();
+ oauth_setup();
+ json0x2dencode_setup();
+ json0x2ddecode_setup();
urlparams_setup();
}
View
@@ -10,11 +10,6 @@
#define LIBRARY_VERSION "0.7.1"
-typedef enum {
- COOKIE,
- OAUTH
-} AuthType;
-
/* reading / writing data in HTTP requests */
typedef struct memory_struct {
char *memory;
@@ -29,30 +24,18 @@ typedef struct key_value_pair {
struct key_value_pair *next;
} t_key_value_pair;
-/* [rest-json] */
+/* [rest] */
typedef struct rest {
t_object x_ob;
- t_outlet *done_outlet;
t_outlet *status_info_outlet;
- int out_count;
char base_url[MAXPDSTRING];
- /* authentication: cookie / oauth */
- AuthType auth_type;
- union {
- struct {
- char login_path[MAXPDSTRING];
- char username[MAXPDSTRING];
- char password[MAXPDSTRING];
- char auth_token[MAXPDSTRING];
- } cookie;
- struct {
- char request_type[5]; /*GET or POST*/
- char client_key[MAXPDSTRING];
- char client_secret[MAXPDSTRING];
- char token_key[MAXPDSTRING];
- char token_secret[MAXPDSTRING];
- } oauth;
- } auth;
+ /* authentication: cookie */
+ struct {
+ char login_path[MAXPDSTRING];
+ char username[MAXPDSTRING];
+ char password[MAXPDSTRING];
+ char auth_token[MAXPDSTRING];
+ } cookie;
t_atom *out;
/* threading */
char request_type[7]; /*One of GET, PUT, POST; DELETE*/
@@ -62,6 +45,28 @@ typedef struct rest {
/* end threading */
} t_rest;
+/* [oauth] */
+typedef struct oauth {
+ t_object x_ob;
+ t_outlet *status_info_outlet;
+ char base_url[MAXPDSTRING];
+ /* authentication*/
+ struct {
+ char request_type[5]; /*GET or POST*/
+ char client_key[MAXPDSTRING];
+ char client_secret[MAXPDSTRING];
+ char token_key[MAXPDSTRING];
+ char token_secret[MAXPDSTRING];
+ } oauth;
+ t_atom *out;
+ /* threading */
+ char request_type[7]; /*One of GET, PUT, POST; DELETE*/
+ char parameters[MAXPDSTRING];
+ char complete_url[MAXPDSTRING];
+ short is_data_locked;
+ /* end threading */
+} t_oauth;
+
/* [json-encode] */
typedef struct json_encode {
t_object x_ob;
@@ -84,16 +89,21 @@ typedef struct urlparams {
int data_count;
} t_urlparams;
-/* [rest-json] */
-void setup_rest0x2djson(void);
+/* [rest] */
+void rest_setup(void);
void *rest_new(t_symbol *selector, int argcount, t_atom *argvec);
void rest_command(t_rest *x, t_symbol *selector, int argcount, t_atom *argvec);
void rest_url(t_rest *x, t_symbol *selector, int argcount, t_atom *argvec);
-void rest_oauth(t_rest *x, t_symbol *selector, int argcount, t_atom *argvec);
+/* [oauth] */
+void oauth_setup(void);
+void *oauth_new(t_symbol *selector, int argcount, t_atom *argvec);
+
+void oauth_command(t_oauth *x, t_symbol *selector, int argcount, t_atom *argvec);
+void oauth_url(t_oauth *x, t_symbol *selector, int argcount, t_atom *argvec);
/* [json-encode] */
-void setup_json0x2dencode(void);
+void json0x2dencode_setup(void);
void *json_encode_new(t_symbol *selector, int argcount, t_atom *argvec);
void json_encode_free(t_json_encode *x, t_symbol *selector, int argcount, t_atom *argvec);
@@ -103,7 +113,7 @@ void json_encode_array_add(t_json_encode *x, t_symbol *selector, int argcount, t
void json_encode_clear(t_json_encode *x, t_symbol *selector, int argcount, t_atom *argvec);
/* [json-decode] */
-void setup_json0x2ddecode(void);
+void json0x2ddecode_setup(void);
void *json_decode_new(t_symbol *selector, int argcount, t_atom *argvec);
void json_decode_string(t_json_decode *x, t_symbol *data);
Oops, something went wrong.

0 comments on commit 2cee983

Please sign in to comment.