#include #include #include #include #include "ezxml.h" #include "api_key.h" /* NOT PUBLIC */ #ifndef TRUE #define TRUE (0==0) #define FALSE (0!=0) #endif static char PROGNAME[128] = { 'b', 'm', 'n', 'a', '\0' }; #define TAGFILE "/work/www.gtoal.com/flickr/tags.csv" void gettags (char *s) { char *command = malloc (strlen (s) + 128); char *sep; //fprintf(stdout, "Looking for '%s'
\n", s); if (*s == '\0') { return; } s = strdup(s); sprintf (command, "/bin/cat %s", TAGFILE); for (;;) { if ((s == NULL) || (*s == '\0')) break; sep = strchr (s, ' '); if (sep != NULL) *sep++ = '\0'; sprintf (command + strlen (command), "|grep -i '%s'", s); s = sep; } //fprintf(stdout, "Executing '%s'
\n", command); fprintf(stdout, "

BMNA tag list


\n"); fflush (stdout); fflush (stderr); system (command); fflush (stdout); fflush (stderr); } int htoi (int c) { if (('0' <= c) && (c <= '9')) return c - '0'; if (('A' <= c) && (c <= 'F')) return c - 'A' + 10; if (('a' <= c) && (c <= 'f')) return c - 'a' + 10; return 0; } char *replace(char *in, int from, int to) { char *out = strdup(in), *s = out; for (;;) { int c = *in++; if (c == from) c = to; *out++ = c; if (c == '\0') break; } return s; } char * cleanup (char *args) { // clean up arguments. Allow for names like "4-spotted prepona" ... // returns string with spaces between tags char *result, *s = malloc (strlen (args) + 1); result = s; for (;;) { int c = *args++; if (c == '\0') break; if (c == '%') { int c1 = *args++; if (c1 == '\0') break; int c2 = *args++; if (c2 == '\0') break; c = (htoi (c1) << 4) | htoi (c2); } if ((('a' <= c) && (c <= 'z')) || (('A' <= c) && (c <= 'Z')) || c == '+' || c == ' ' || c == '-' || (('0' <= c) && (c <= '9'))) { if (c == '+') { if ((s != result) && (s[-1] != ' ')) *s++ = ' '; } else { *s++ = c; } } else { if ((s != result) && (s[-1] != ' ')) *s++ = ' '; } } *s = '\0'; while (*result == ' ') result += 1; for (;;) { int l = strlen(result); if ((l > 0) && (result[l-1] == ' ')) result[l-1] = '\0'; else break; } return result; // DON'T FREE IT! } FILE * my_popen (char *command, char *opts) { FILE *f, *log; log = fopen ("/tmp/bmna.log", "a"); fprintf (log, "%s\n", command); fclose (log); f = popen (command, opts); return f; } void myexit_ (int rc, int lineno, char *file) { fflush (stdout); fflush (stderr); if (rc != 0) fprintf (stderr, "Exiting %s:%d, Reason %d\n", file, lineno, rc); fflush (stderr); exit (rc); } #define myexit(rc) myexit_(rc, __LINE__, __FILE__) FILE * flickr_photos_search_tags (char *ctags) { char *command = malloc(strlen(ctags)+256); sprintf(command, "wget -q -O - 'http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=%s&group_id=38155409@N00&tags=%s&sort=interestingness-desc'", API_KEY, replace(ctags, ' ', ',')); return my_popen(command, "r"); } FILE * flickr_tags (const char *photoid) { static char command[1024]; sprintf (command, "wget -q -O - 'http://api.flickr.com/services/rest/?method=flickr.tags.getListPhoto&api_key=%s&photo_id=%s'", API_KEY, photoid); return my_popen (command, "r"); } static int nextfreekey = 0; static char *canonkey[1024]; static char *fullkey[1024]; static int count[1024]; #define SWAP(l,r) {char *tmp; int itmp; tmp = canonkey[l]; canonkey[l] = canonkey[r]; canonkey[r] = tmp; \ tmp = fullkey[l]; fullkey[l] = fullkey[r]; fullkey[r] = tmp; \ itmp = count[l]; count[l] = count[r]; count[r] = itmp;} void sort_tags_by_alpha (int l, int u) { for (;;) { int l1, u1, pivot; if (l + 1 == u) { if (strcmp (canonkey[l], canonkey[u]) > 0) SWAP (l, u); return; } if (l >= u) return; l1 = l; u1 = u; pivot = (l + u) / 2; for (;;) { while (strcmp (canonkey[l], canonkey[pivot]) < 0) l += 1; while (strcmp (canonkey[pivot], canonkey[u]) < 0) u -= 1; if (l >= u) break; SWAP (l, u); l++; u--; } sort_tags_by_alpha (l1, l); l = u; u = u1; } } void sort_tags_by_count (int l, int u) { for (;;) { int l1, u1, pivot; if (l + 1 == u) { if (count[l] > count[u]) SWAP (l, u); return; } if (l >= u) return; l1 = l; u1 = u; pivot = (l + u) / 2; for (;;) { while ((count[l] < count[pivot]) || ((count[l] == count[pivot]) && (strcmp (canonkey[l], canonkey[pivot]) < 0))) l += 1; while ((count[pivot] < count[u]) || ((count[pivot] == count[u]) && (strcmp (canonkey[pivot], canonkey[u]) < 0))) u -= 1; if (l >= u) break; SWAP (l, u); l++; u--; } sort_tags_by_count (l1, l); l = u; u = u1; } } void bmna_count_tag (const char *canon, const char *fullname) // POOR IMPLEMENTATION for now. Quick & Dirty to get something working. { int i; if (strcmp (canon, "bmna") == 0) return; if (strchr (canon, 0251 /* (c) */ ) != NULL) return; canonkey[nextfreekey] = strdup (canon); fullkey[nextfreekey] = strdup (fullname); for (i = 0; i <= nextfreekey; i++) { if (strcmp (canon, canonkey[i]) == 0) break; } if (i == nextfreekey) nextfreekey++; count[i] += 1; } void print_tag_cloud (void) { int i; fprintf (stdout, "

Tag Cloud of associated concepts

\n"); for (i = 0; i < nextfreekey; i++) { if (count[i] > 0) fprintf (stdout, "%s  ", count[i], canonkey[i], fullkey[i]); } fprintf (stdout, "
\n"); } void html_display_photo (ezxml_t photo) { FILE *xml_file; ezxml_t xml, xphoto, tags, tag; fprintf (stdout, "", ezxml_attr (photo, "owner"), ezxml_attr (photo, "id")); fprintf (stdout, "\"%s\"","); fprintf (stdout, "\n"); xml_file = flickr_tags (ezxml_attr (photo, "id")); if (xml_file == NULL) { fprintf (stderr, "Tag search failed\n"); myexit (EXIT_FAILURE); } xml = ezxml_parse_fp (xml_file); xphoto = ezxml_child (xml, "photo"); tags = ezxml_child (xphoto, "tags"); for (tag = ezxml_child (tags, "tag"); tag != NULL; tag = tag->next) { // fprintf(stdout, "%s:%s
\n", tag->txt, ezxml_attr(tag, "raw")); bmna_count_tag (tag->txt, ezxml_attr (tag, "raw")); } ezxml_free (tags); } int main (int argc, char **argv) { FILE *xml_file; ezxml_t xml; ezxml_t photo; char *args; char *progname; progname = strrchr(argv[0], '/'); if (progname != NULL) strcpy(PROGNAME, progname+1); fprintf (stdout, "Content-Type: text/html\n\n"); fprintf (stdout, "\nBMNA tagger\n\n"); args = getenv ("QUERY_STRING"); fprintf (stdout, "
\n", PROGNAME); fprintf (stdout, "Search For A Butterfly: \n"); fprintf (stdout, "
\n"); gettags (args); if ((args != NULL) && (*args != '\0')) { char *tags = malloc (strlen (args) + 128); sprintf (tags, "bmna,%s", replace(args, ' ', ',')); xml_file = flickr_photos_search_tags (tags); if (xml_file == NULL) { fprintf (stderr, "Search failed\n"); myexit (EXIT_FAILURE); } fprintf(stdout, "

Photos for ID help

\n"); xml = ezxml_parse_fp (xml_file); for (photo = ezxml_child (ezxml_child (xml, "photos"), "photo"); photo != NULL; photo = photo->next) { html_display_photo (photo); } ezxml_free (xml); sort_tags_by_count (0, nextfreekey - 1); { int i, q1 = (nextfreekey - 1) / 4, q2 = (nextfreekey - 1) / 2, q3 = ((nextfreekey - 1) * 3) / 4; for (i = 0; i < q1; i++) count[i] = 0; for (i = q1; i < q2; i++) count[i] = 1; for (i = q2; i < q3; i++) count[i] = 2; for (i = q3; i < nextfreekey; i++) count[i] = 4; } sort_tags_by_alpha (0, nextfreekey - 1); print_tag_cloud (); } fprintf (stdout, "\n\n"); myexit (EXIT_SUCCESS); return (0); }