Created
July 18, 2012 19:54
-
-
Save jbedo/3138466 to your computer and use it in GitHub Desktop.
reddit client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<u.h> | |
#include<libc.h> | |
#include<json.h> | |
#include<bio.h> | |
#include<String.h> | |
const char url[] = "http://www.reddit.com/.json?feed=ffffffffffffffffffffffffffffffffffffffff&user=jbedo"; | |
/* Does the webfs query */ | |
String * | |
fetch(void) | |
{ | |
int ctlfd; | |
Biobuf *body; | |
char buf[1024]; | |
int c, id, n; | |
String *json; | |
if((ctlfd = open("/mnt/web/clone", ORDWR)) < 0) | |
sysfatal("fetch: cannot clone: %r"); | |
if((n = read(ctlfd, buf, sizeof buf-1)) < 0) | |
sysfatal("fetch: cannot clone: %r"); | |
buf[n] = '\0'; | |
id = atoi(buf); | |
if(id < 0) | |
sysfatal("fetch: invalid id: %d", id); | |
n = snprint(buf, sizeof buf-1, "url %s", url); | |
if(write(ctlfd, buf, n) != n) | |
sysfatal("fetch: unable to set url: %r"); | |
json = s_new(); | |
snprint(buf, sizeof buf-1, "/mnt/web/%d/body", id); | |
if((body = Bopen(buf, OREAD)) == nil) | |
sysfatal("fetch: cannot fetch url: %r"); | |
while((c = Bgetc(body)) > 0) | |
s_putc(json, c); | |
s_terminate(json); | |
Bterm(body); | |
close(ctlfd); | |
return json; | |
} | |
/* Reddit parser */ | |
void | |
childdata(Jparser *p, int root) | |
{ | |
int tok; | |
if(p->tokens[root].type != JObj) | |
sysfatal("child: expecting obj"); | |
if((tok = Jfind(p, root, "title")) < 0 || | |
p->tokens[tok].type != JStr) | |
sysfatal("childdata: couldn't parse title"); | |
print("%s\n", Jtokstr(&p->tokens[tok])); | |
if((tok = Jfind(p, root, "url")) < 0 || | |
p->tokens[tok].type != JStr) | |
sysfatal("childdata: couldn't parse url"); | |
print("\t%s", Jtokstr(&p->tokens[tok])); | |
if((tok = Jfind(p, root, "subreddit")) < 0 || | |
p->tokens[tok].type != JStr) | |
sysfatal("childdata: couldn't parse subreddit"); | |
print("\t%s\n", Jtokstr(&p->tokens[tok])); | |
} | |
void | |
child(Jparser *p, int root) | |
{ | |
int tok; | |
if(p->tokens[root].type != JObj || | |
(tok = Jfind(p, root, "kind")) < 0 || | |
strcmp(Jtokstr(&p->tokens[tok]), "t3") != 0) | |
return; | |
if((tok = Jfind(p, root, "data")) < 0) | |
sysfatal("child: couldn't parse data"); | |
childdata(p, tok); | |
} | |
void | |
data(Jparser *p, int root) | |
{ | |
int i, tok, children; | |
if(p->tokens[root].type != JObj) | |
sysfatal("data: expecting data object"); | |
if((children = Jfind(p, root, "children")) < 0) | |
sysfatal("data: cannot find children"); | |
for(i = 0, tok = children+1; i < p->tokens[children].nsub; i++, tok = Jnext(p, tok)){ | |
print("%d/\t", i+1); | |
child(p, tok); | |
} | |
} | |
void | |
top(Jparser *p) | |
{ | |
int tok; | |
if(p->tokens[0].type != JObj || | |
(tok = Jfind(p, 0, "kind")) < 0 || | |
strcmp(Jtokstr(&p->tokens[tok]), "Listing") != 0) | |
sysfatal("top: expecting listing"); | |
if((tok = Jfind(p, 0, "data")) < 0) | |
sysfatal("top: cannot find data attribute"); | |
data(p, tok); | |
} | |
void | |
usage(void) | |
{ | |
fprint(2, "No arguments accepted\n"); | |
exits("usage"); | |
} | |
void | |
main(int argc, char *argv[]) | |
{ | |
String *json; | |
Jparser p; | |
ARGBEGIN{ | |
case 'h': | |
usage(); | |
}ARGEND; | |
if(argc != 0) | |
usage(); | |
json = fetch(); | |
Jinit(&p); | |
if(Jtokenise(&p, s_to_c(json)) < 0) | |
sysfatal("JSON tokenisation error: %r"); | |
top(&p); | |
exits(0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment