Skip to content

Instantly share code, notes, and snippets.

@jbedo
Created July 18, 2012 19:54
Show Gist options
  • Save jbedo/3138466 to your computer and use it in GitHub Desktop.
Save jbedo/3138466 to your computer and use it in GitHub Desktop.
reddit client
#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