root/lang/cplusplus/twitter-v8/trunk/wassr.cc

Revision 18822, 7.5 kB (checked in by mattn, 4 months ago)

move to trunk.

Line 
1#include <v8.h>
2#include <cstring>
3#include <cstdio>
4#include <cstdlib>
5#include <curl/curl.h>
6#include "wassr.h"
7
8#define SERVICE_UPDATE_URL           "http://api.wassr.jp/statuses/update.json"
9#define SERVICE_FRIENDS_TIMELINE_URL "http://api.wassr.jp/statuses/friends_timeline.json"
10#define SERVICE_USER_TIMELINE_URL    "http://api.wassr.jp/statuses/user_timeline.json"
11#define SERVICE_PUBLIC_TIMELINE_URL  "http://api.wassr.jp/statuses/public_timeline.json"
12
13static char* response_data = NULL;  /* response data from server. */
14static size_t response_size = 0;    /* response size of data */
15static size_t handle_returned_data(char* ptr, size_t size, size_t nmemb, void* stream) {
16  if (!response_data) {
17    response_data = new char[size*nmemb];
18  } else {
19    char* response_tmp = new char[response_size+size*nmemb];
20    memset(response_tmp, 0, response_size+size*nmemb);
21    memcpy(response_tmp, response_data, response_size);
22    delete[] response_data;
23    response_data = response_tmp;
24  }
25  if (response_data) {
26    memcpy(response_data+response_size, ptr, size*nmemb);
27    response_size += size*nmemb;
28  }
29  return size*nmemb;
30}
31
32v8::Handle<v8::Value> WassrUpdateStatus(const v8::Arguments& args) {
33  v8::HandleScope handle_scope;
34  v8::TryCatch try_catch;
35
36  if (args.Length() != 1) return v8::ThrowException(v8::String::New("Error: usage is updateStatus(message)"));
37
38  v8::Handle<v8::Value> ret = v8::Undefined();
39  v8::Local<v8::Object> This = args.This();
40
41  v8::String::AsciiValue username(This->Get(v8::String::New("username")));
42  v8::String::AsciiValue password(This->Get(v8::String::New("password")));
43
44  v8::Handle<v8::Object> global = v8::Context::GetCurrent()->Global();
45  v8::Local<v8::Function> func = v8::Function::Cast(*global->Get(v8::String::New("encodeURIComponent")));
46  v8::Local<v8::Value> funcargs[1];
47  funcargs[0] = args[0]->ToString();
48  v8::Local<v8::Value> result_val = func->Call(global, 1, funcargs);
49  v8::String::AsciiValue escaped(result_val->ToString());
50  char *status = *escaped;
51
52  CURL* curl = NULL;
53  CURLcode res = CURLE_OK;
54  char *auth;
55  char *url;
56
57  response_data = NULL;
58  response_size = 0;
59  curl = curl_easy_init();
60  if (!curl) return v8::ThrowException(v8::String::New("Error: unknown"));
61
62  int n_url = strlen(SERVICE_UPDATE_URL) + 8 + strlen(status) + 1;
63  url = new char[n_url];
64  memset(url, 0, n_url);
65  strcpy(url, SERVICE_UPDATE_URL);
66  strcat(url, "?status=");
67  strcat(url, status);
68
69  int n_auth = strlen(*username) + 1 + strlen(*password) + 1;
70  auth = new char[n_auth];
71  memset(auth, 0, n_auth);
72  strcpy(auth, *username);
73  strcat(auth, ":");
74  strcat(auth, *password);
75
76  curl_easy_setopt(curl, CURLOPT_URL, url);
77  curl_easy_setopt(curl, CURLOPT_USERPWD, auth);
78  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, handle_returned_data);
79  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
80  curl_easy_setopt(curl, CURLOPT_POST, 1);
81  curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
82  res = curl_easy_perform(curl);
83  int stat = 0;
84  res == CURLE_OK ? curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &stat) : res;
85  curl_easy_cleanup(curl);
86
87  delete[] auth;
88  delete[] url;
89
90  if (res != CURLE_OK) {
91    ret = v8::ThrowException(v8::String::New("Error: unknown"));
92  }
93  if (response_data) {
94    delete[] response_data;
95    response_data = NULL;
96  }
97  return ret;
98}
99
100static v8::Handle<v8::Value> WassrTimeline(const char* url, const char* username, const char* password) {
101  v8::Handle<v8::Value> ret = v8::Undefined();
102
103  CURL* curl = NULL;
104  CURLcode res = CURLE_OK;
105  char *auth;
106
107  response_data = NULL;
108  response_size = 0;
109  curl = curl_easy_init();
110  if (!curl) return v8::ThrowException(v8::String::New("Error: unknown"));
111
112  int n_auth = strlen(username) + 1 + strlen(password) + 1;
113  auth = new char[n_auth];
114  memset(auth, 0, n_auth);
115  strcpy(auth, username);
116  strcat(auth, ":");
117  strcat(auth, password);
118
119  curl_easy_setopt(curl, CURLOPT_URL, url);
120
121  curl_easy_setopt(curl, CURLOPT_USERPWD, auth);
122  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, handle_returned_data);
123  curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
124  res = curl_easy_perform(curl);
125  int stat = 0;
126  res == CURLE_OK ? curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &stat) : res;
127  curl_easy_cleanup(curl);
128
129  delete[] auth;
130
131  if (res == CURLE_OK) {
132    char* json = new char[response_size+1];
133    memset(json, 0, response_size+1);
134    memcpy(json, (char*) response_data, response_size);
135    v8::Handle<v8::String> source = v8::String::New(json);
136    delete[] json;
137
138    v8::Handle<v8::Script> script = v8::Script::Compile(source);
139    if (script.IsEmpty()) {
140      ret = v8::ThrowException(v8::String::New("Error: unknown"));
141      goto leave;
142    }
143    v8::Handle<v8::Value> result = script->Run();
144    if (script.IsEmpty()) {
145      ret = v8::ThrowException(v8::String::New("Error: unknown"));
146      goto leave;
147    }
148    if (!result->IsArray()) {
149      ret = v8::ThrowException(v8::String::New("Error: unknown"));
150      goto leave;
151    }
152    ret = result;
153  }
154
155leave:
156  if (response_data) {
157    delete[] response_data;
158    response_data = NULL;
159  }
160  return ret;
161}
162
163v8::Handle<v8::Value> WassrFriendsTimeline(const v8::Arguments& args) {
164  v8::HandleScope handle_scope;
165  v8::TryCatch try_catch;
166
167  if (args.Length() != 0) return v8::ThrowException(v8::String::New("Error: usage is friendsTimeline()"));
168
169  v8::Handle<v8::Value> ret = v8::Undefined();
170  v8::Handle<v8::Object> This = args.This();
171
172  v8::String::AsciiValue username(This->Get(v8::String::New("username")));
173  v8::String::AsciiValue password(This->Get(v8::String::New("password")));
174
175  int n_targeturl = strlen(SERVICE_FRIENDS_TIMELINE_URL) + 4 + strlen(*username) + 1;
176  char* targeturl = new char[n_targeturl];
177  memset(targeturl, 0, n_targeturl);
178  strcpy(targeturl , SERVICE_FRIENDS_TIMELINE_URL);
179  strcat(targeturl , "?id=");
180  strcat(targeturl , *username);
181  ret = WassrTimeline(targeturl, *username, *password);
182  delete[] targeturl;
183
184  return ret;
185}
186
187v8::Handle<v8::Value> WassrUserTimeline(const v8::Arguments& args) {
188  v8::HandleScope handle_scope;
189  v8::TryCatch try_catch;
190
191  if (args.Length() != 1) return v8::ThrowException(v8::String::New("Error: usage is userTimeline(username)"));
192
193  v8::Handle<v8::Value> ret = v8::Undefined();
194  v8::Handle<v8::Object> This = args.This();
195
196  v8::String::AsciiValue target(args[0]);
197  v8::String::AsciiValue username(This->Get(v8::String::New("username")));
198  v8::String::AsciiValue password(This->Get(v8::String::New("password")));
199
200  int n_targeturl = strlen(SERVICE_USER_TIMELINE_URL) + 4 + strlen(*target) + 1;
201  char* targeturl = new char[n_targeturl];
202  memset(targeturl, 0, n_targeturl);
203  strcpy(targeturl , SERVICE_USER_TIMELINE_URL);
204  strcat(targeturl , "?id=");
205  strcat(targeturl , *target);
206  ret = WassrTimeline(targeturl, *username, *password);
207  delete[] targeturl;
208
209  return ret;
210}
211
212v8::Handle<v8::Value> WassrPublicTimeline(const v8::Arguments& args) {
213  v8::HandleScope handle_scope;
214  v8::TryCatch try_catch;
215
216  if (args.Length() != 0) return v8::ThrowException(v8::String::New("Error: usage is publicTimeline()"));
217
218  v8::Handle<v8::Value> ret = v8::Undefined();
219  v8::Handle<v8::Object> This = args.This();
220
221  v8::String::AsciiValue username(This->Get(v8::String::New("username")));
222  v8::String::AsciiValue password(This->Get(v8::String::New("password")));
223  return WassrTimeline(SERVICE_PUBLIC_TIMELINE_URL, *username, *password);
224}
Note: See TracBrowser for help on using the browser.