Wspominałem już, że nie jestem programistą? Dlatego proszę o wszelkie uwagi odnośnie poniższego kodu.
Jest to prosty klient Blip, który w zasadzie tylko pobiera statusy konkretnego użytkownika (^user) lub o konkretnym znaczniku (#tag).
/* Bartłomiej guzik Syryjczyk
* 2010-10-11
*/
#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>
#include <json/json.h>
int fnc(void *ptr, size_t size, size_t nmemb, void *stream) {
json_object * new_obj;
json_object * jvalue;
new_obj = json_tokener_parse(ptr);
if(json_object_get_type(new_obj) == json_type_array)
for (int i=0; i<json_object_array_length(new_obj); i++) {
jvalue = json_object_array_get_idx(new_obj, i);
printf("%s\t", json_object_get_string(json_object_object_get(jvalue, "user_path"))+7);
printf("%s\t", json_object_get_string(json_object_object_get(jvalue, "created_at")));
printf("%s\n", json_object_get_string(json_object_object_get(jvalue, "body")));
}
return 0;
}
int main(int argc, char* argv[]) {
CURL *curl;
CURLcode res;
struct curl_slist *slist = NULL;
char *tag = "tag", *user = "";
char url[64];
int limit = 3, offset = 0, debug = 0;
for(int i = 1; i < argc; i++) {
if (argv[i][0] == '-')
switch (argv[i][1]) {
case 't':
tag = argv[++i];
break;
case 'u':
user = argv[++i];
break;
case 'l':
limit = atoi(argv[++i]);
break;
case 'o':
offset = atoi(argv[++i]);
break;
case 'v':
debug = 1;
break;
}
}
curl = curl_easy_init();
if(curl) {
curl_easy_setopt(curl, CURLOPT_VERBOSE, debug);
curl_easy_setopt(curl, CURLOPT_ENCODING, "UTF-8");
curl_easy_setopt(curl, CURLOPT_USERAGENT, "gift-0.2 Infowizja.pl");
slist = curl_slist_append(slist, "Accept: application/json");
slist = curl_slist_append(slist, "X-Blip-API: 0.02");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
for (int cnt = 0; cnt < limit; cnt++) {
if (strcmp(user, "\0"))
sprintf(url, "blip.pl/users/%s/statuses?limit=1&offset=%d", user, offset+cnt);
else
sprintf(url, "blip.pl/tags/%s?limit=1&offset=%d", tag, offset+cnt);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, fnc);
res = curl_easy_perform(curl);
}
}
curl_easy_cleanup(curl);
return 0;
}
Kompilacja:
gcc -std=c99 -g -O3 -Wall -c -o blip.o blip.c
W linii 59 jest nazwa klienta, która nie wiem co oznacza. Bodajże „t” oznaczało twitter, bo początkowo miały być obsługiwane tweetnięcia (dorobię wkrótce).
Cały kod jest częścią większego projektu pisanego dla Infowizji.
Czujcie się swobodnie przerabiając ten kod, ale dajcie znać, jak coś udoskonalicie. Blip API jest dość zrozumiałe.
Z json-c mam problem. Przekazywanie większych tablic (np. ponad 3 statusy Blip) daje Segmentation fault. Z tego powodu robiona jest sztuczka z limit i offset (pętla zaczyna się w linii 63).
Tak samo problematyczny jest znak „>”. Dlatego proszę nie używać uśmieszków jak informujecie przyjaciół o swoich poczynaniach :>
Nie zrozumiałem CURLOPT_WRITEDATA, więc wywołanie programu (z opcją -v) kończy się komunikatem:
* Failed writing body (0 != 324)
* Closing connection #0
* Failed writing received data to disk/application
Jeśli ustawiacie dodatkowe nagłówki za pomocą curl_slist_append() (u mnie linie 60-62), pamiętajcie, że append w nazwie funkcji robi append. Ustawienie tego samego nagłówek kilka razy skutkuje odpowiedzią serwera:
HTTP/1.1 400 Bad Request
Napisałem też identycznego klienta w Perl. Ale coś się zagubił w repozytorium…
[...] południu opublikowałem źródła klienta Blip w C, teraz odnalazłem kod w Perl (mniej funkcjonalny) i wklejam [...]
[...] klienta twitter poniżej. W zasadzie to tylko mała zmiana w stosunku do klienta Blip, bo różnią się formatem danych wejściowych (ale nadal to JSON) i nazwami pól (user_path -> [...]