とりあえず statuses/sample を持ってくる
「pingpong003ワークショップ@公立はこだて未来大学」に参加したのがきっかけで,「#ppfun」というハッシュタグを付けたつぶやきを流すアプリケーションをひそかに作っています.
そこで見つけたのがこれ,Twitter の Streaming APIをいじってみました.
キーワードやユーザIDなどでつぶやきにフィルタをかけて,リアルタイムに取得できるみたいです.
Twitter クライアントというよりは,つぶやきを流し続けたり,蓄積して分析したりするような使い方をするならとっても適しているような気がします.
まだ直さないといけないところが残っていますが,とりあえず statuses/sample からつぶやきとニックネームを取得して出力するものを公開します.
statuses/filter を使ったものももうすぐ公開します.
今回お世話になったみなさん,とてもとても感謝です.
- cURL and libcurl
- バベル - extra - C++ - TrickLibrary
- Kazuho@Cybozu Labs: 今更 C++ で JSON パーサ「picojson」を書いたわけ
[追記]
isLimit 関数ですが,delete が来るおは受け取ったステータスに欠落部分がある時でしたね.
#include <iostream> using namespace std; #include "./curl/curl.h" #include "./babel/babel.h" #include "./picojson.h" using namespace picojson; #define CR 13 #define LF 10 struct MemoryStruct { char *memory; size_t size; }; bool isLimit(value *pv) { value obj = pv->get("delete"); if (obj == NULL) return false; else return true; } static void *myrealloc(void *ptr, size_t size) { /* There might be a realloc() out there that doesn't like reallocing NULL pointers, so we take care of it here */ if(ptr) return realloc(ptr, size); else return malloc(size); } static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, MemoryStruct *data) { size_t realsize = size * nmemb; data->memory = (char *)myrealloc(data->memory, data->size + realsize + 1); if (data->memory) { memcpy(&(data->memory[data->size]), ptr, realsize); data->size += realsize; data->memory[data->size] = 0; } // picojson if (CR == data->memory[data->size-2] && LF == data->memory[data->size-1]) // Parsing Responses { value v; string err; parse(v, data->memory, data->memory + data->size, &err); if (isLimit(&v)) // Track Limiting { exit(0); // cleanup してない } if (err.empty()) { const string key("usr"); object obj = v.get<object>(); value usr = v.get("user"); object obj_usr = usr.get<object>(); string screen_name(obj_usr["screen_name"].to_str()); string text(obj["text"].to_str()); cout << screen_name << ": " << babel::utf8_to_sjis(text) << endl; data->memory = NULL; data->size = 0; } } return realsize; } int main(int argc, char **argv) { // babel babel::init_babel(); // cURL CURL *curl_handle; CURLcode res; struct MemoryStruct chunk; chunk.memory=NULL; /* we expect realloc(NULL, size) to work */ chunk.size = 0; /* no data at this point */ curl_handle = curl_easy_init(); curl_easy_setopt(curl_handle, CURLOPT_PROXY, "192.168.0.1:8080"); curl_easy_setopt(curl_handle, CURLOPT_PROXYUSERPWD, "PROXY_USER_NAME:PROXY_PASSWORD"); curl_easy_setopt(curl_handle, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY); curl_easy_setopt(curl_handle, CURLOPT_USERPWD, "TWITTER_ID:TWITTER_PASSWORD"); if(curl_handle) { curl_easy_setopt(curl_handle, CURLOPT_URL, "http://stream.twitter.com/1/statuses/sample.json"); /* send all data to this function */ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); /* we pass our 'chunk' struct to the callback function */ curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); res = curl_easy_perform(curl_handle); /* always cleanup */ curl_easy_cleanup(curl_handle); } return 0; }
さて,libcurl や picojson をもっと上手に使えるように勉強しなくちゃ_〆(・・o)