/** * flickcurl_serialize_photo: * @fcs: flickcurl serializer object * @photo: photo object * * Serialize photo description to RDF triples * * Return value: non-0 on failure */ int flickcurl_serialize_photo(flickcurl_serializer* fcs, flickcurl_photo* photo) { int i; int need_person=0; int need_foaf=0; int need_rdfs=0; flickrdf_nspace* nspaces=NULL; flickrdf_nspace* ns; flickcurl_serializer_factory* fsf=fcs->factory; flickcurl* fc=fcs->fc; #if FLICKCURL_DEBUG > 1 FILE* fh=stderr; const char* label="libflickcurl"; #endif flickcurl_size** sizes=NULL; if(!photo) return 1; /* Always add XSD, RDF and Flickr namespaces */ nspaces=nspace_add_if_not_declared(nspaces, NULL, XSD_NS); nspaces=nspace_add_if_not_declared(nspaces, "rdf", RDF_NS); nspaces=nspace_add_if_not_declared(nspaces, "flickr", FLICKR_NS); if(photo->place) nspaces=nspace_add_if_not_declared(nspaces, "places", PLACES_NS); sizes=flickcurl_photos_getSizes(fc, photo->id); if(sizes) { need_foaf=1; need_rdfs=1; } /* mark namespaces used in fields */ for(i=PHOTO_FIELD_FIRST; i <= PHOTO_FIELD_LAST; i++) { flickcurl_photo_field_type field=(flickcurl_photo_field_type)i; flickcurl_field_value_type datatype=photo->fields[field].type; int f; if(datatype == VALUE_TYPE_NONE) continue; for(f=0; field_table[f].field != PHOTO_FIELD_none; f++) { if(field_table[f].field != field) continue; if(field_table[f].flags & FIELD_FLAGS_PERSON) need_person=1; nspaces=nspace_add_if_not_declared(nspaces, NULL, field_table[f].nspace_uri); break; } } /* in tags look for xmlns:PREFIX="URI" otherwise look for PREFIX: */ for(i=0; i < photo->tags_count; i++) { char* prefix; char *p; flickcurl_tag* tag=photo->tags[i]; if(!strncmp(tag->raw, "xmlns:", 6)) { prefix=&tag->raw[6]; for(p=prefix; *p && *p != '='; p++) ; if(!*p) /* "xmlns:PREFIX" seen */ continue; /* "xmlns:PREFIX=" seen */ *p='\0'; nspaces=nspace_add_new(nspaces, prefix, p+1); #if FLICKCURL_DEBUG > 1 fprintf(fh, "%s: Found declaration of namespace prefix %s uri %s in tag '%s'\n", label, prefix, p+1, tag->raw); #endif *p='='; continue; } prefix=tag->raw; for(p=prefix; *p && *p != ':'; p++) ; if(!*p) /* "PREFIX:" seen */ continue; *p='\0'; nspaces=nspace_add_if_not_declared(nspaces, prefix, NULL); *p=':'; } if(need_person) { need_foaf=1; nspaces=nspace_add_if_not_declared(nspaces, "dc", DCTERMS_NS); } if(need_foaf) nspaces=nspace_add_if_not_declared(nspaces, "foaf", FOAF_NS); if(need_rdfs) nspaces=nspace_add_if_not_declared(nspaces, "rdfs", RDFS_NS); #if FLICKCURL_DEBUG > 1 print_nspaces(fh, label, nspaces); #endif /* generate seen namespace declarations */ for(ns=nspaces; ns; ns=ns->next) fsf->emit_namespace(fcs->data, ns->prefix, ns->prefix_len, ns->uri, ns->uri_len); if(need_person) { fsf->emit_triple(fcs->data, photo->uri, FLICKCURL_TERM_TYPE_RESOURCE, DCTERMS_NS, "creator", "person", FLICKCURL_TERM_TYPE_BLANK, NULL); fsf->emit_triple(fcs->data, "person", FLICKCURL_TERM_TYPE_BLANK, RDF_NS, "type", FOAF_NS "Person", FLICKCURL_TERM_TYPE_RESOURCE, NULL); fsf->emit_triple(fcs->data, "person", FLICKCURL_TERM_TYPE_BLANK, FOAF_NS, "maker", photo->uri, FLICKCURL_TERM_TYPE_RESOURCE, NULL); } /* generate triples from fields */ for(i=PHOTO_FIELD_FIRST; i <= PHOTO_FIELD_LAST; i++) { flickcurl_photo_field_type field=(flickcurl_photo_field_type)i; flickcurl_field_value_type datatype=photo->fields[field].type; int f; if(datatype == VALUE_TYPE_NONE) continue; for(f=0; field_table[f].field != PHOTO_FIELD_none; f++) { const char* datatype_uri=NULL; char* object=NULL; char* new_object=NULL; int type= FLICKCURL_TERM_TYPE_LITERAL; if(field_table[f].field != field) continue; #if FLICKCURL_DEBUG > 1 fprintf(fh, "%s: field %s (%d) with %s value: '%s' has predicate %s%s\n", label, flickcurl_get_photo_field_label(field), field, flickcurl_get_field_value_type_label(datatype), photo->fields[field].string, field_table[f].nspace_uri, field_table[f].name); #endif object=photo->fields[field].string; if(field_table[f].flags & FIELD_FLAGS_STRING) { datatype=VALUE_TYPE_STRING; } else if(field_table[f].flags & FIELD_FLAGS_FLOAT) { datatype=VALUE_TYPE_FLOAT; } else if(field_table[f].flags & FIELD_FLAGS_SQL_DATE) { new_object=flickcurl_sqltimestamp_to_isotime(object); object=new_object; datatype=VALUE_TYPE_DATETIME; } if(field == PHOTO_FIELD_license) { flickcurl_license* license; license=flickcurl_photos_licenses_getInfo_by_id(fc, photo->fields[field].integer); if(!license) continue; if(license->url) { datatype=VALUE_TYPE_URI; object=license->url; } else { datatype=VALUE_TYPE_STRING; object=license->name; } } switch(datatype) { case VALUE_TYPE_BOOLEAN: datatype_uri= XSD_NS "boolean"; break; case VALUE_TYPE_DATETIME: datatype_uri= XSD_NS "dateTime"; break; case VALUE_TYPE_FLOAT: datatype_uri= XSD_NS "double"; break; case VALUE_TYPE_INTEGER: datatype_uri= XSD_NS "integer"; break; case VALUE_TYPE_STRING: break; case VALUE_TYPE_URI: type= FLICKCURL_TERM_TYPE_RESOURCE; break; case VALUE_TYPE_NONE: case VALUE_TYPE_PHOTO_ID: case VALUE_TYPE_PHOTO_URI: case VALUE_TYPE_UNIXTIME: case VALUE_TYPE_PERSON_ID: case VALUE_TYPE_MEDIA_TYPE: case VALUE_TYPE_TAG_STRING: case VALUE_TYPE_COLLECTION_ID: case VALUE_TYPE_ICON_PHOTOS: default: break; } if(field_table[f].flags & FIELD_FLAGS_PERSON) fsf->emit_triple(fcs->data, "person", FLICKCURL_TERM_TYPE_BLANK, field_table[f].nspace_uri, field_table[f].name, object, type, datatype_uri); else fsf->emit_triple(fcs->data, photo->uri, FLICKCURL_TERM_TYPE_RESOURCE, field_table[f].nspace_uri, field_table[f].name, object, type, datatype_uri); if(new_object) free(new_object); break; } } /* generate triples from tags */ for(i=0; i < photo->tags_count; i++) { flickcurl_tag* tag=photo->tags[i]; char* prefix; char *p; char *f; char *v; size_t value_len; prefix=&tag->raw[0]; if(!strncmp(prefix, "xmlns:", 6)) continue; for(p=prefix; *p && *p != ':'; p++) ; if(!*p) /* No ':' found */ continue; /* ":" seen */ *p='\0'; f=p+1; for(v=f; *v && *v != '='; v++) ; if(!*v) /* "prefix:name" seen with no value */ continue; /* zap = */ *v++='\0'; value_len=strlen(v); if(*v == '"') { v++; if(v[value_len-1]=='"') v[--value_len]='\0'; } ns=nspace_get_by_prefix(nspaces, prefix); #if FLICKCURL_DEBUG > 1 fprintf(fh, "%s: tag with prefix '%s' field '%s' value '%s' namespace uri %s\n", label, prefix, f, v, ns ? ns->uri : "(No namespace)"); #endif if(!ns) continue; fsf->emit_triple(fcs->data, photo->uri, FLICKCURL_TERM_TYPE_RESOURCE, ns->uri, f, v, FLICKCURL_TERM_TYPE_LITERAL, NULL); } /* generate triples from places */ if(photo->place) { char place_bnode[7]={'p', 'l', 'a', 'c', 'e', 'X', '\0'}; flickcurl_place* place=photo->place; for(i=(int)0; i <= (int)FLICKCURL_PLACE_LAST; i++) { char* name=place->names[i]; char* id=place->ids[i]; char* url=place->urls[i]; char* woe_id=place->woe_ids[i]; if(!name && !id && !url && !woe_id) continue; place_bnode[5]='0'+i; fsf->emit_triple(fcs->data, photo->uri, FLICKCURL_TERM_TYPE_RESOURCE, PLACES_NS, "place", place_bnode, FLICKCURL_TERM_TYPE_BLANK, NULL); fsf->emit_triple(fcs->data, place_bnode, FLICKCURL_TERM_TYPE_BLANK, RDF_NS, "type", PLACES_NS "Place", FLICKCURL_TERM_TYPE_RESOURCE, NULL); fsf->emit_triple(fcs->data, place_bnode, FLICKCURL_TERM_TYPE_BLANK, PLACES_NS, "type", flickcurl_get_place_type_label((flickcurl_place_type)i), FLICKCURL_TERM_TYPE_LITERAL, NULL); if(name) fsf->emit_triple(fcs->data, place_bnode, FLICKCURL_TERM_TYPE_BLANK, PLACES_NS, "name", name, FLICKCURL_TERM_TYPE_LITERAL, NULL); if(id) fsf->emit_triple(fcs->data, place_bnode, FLICKCURL_TERM_TYPE_BLANK, PLACES_NS, "id", id, FLICKCURL_TERM_TYPE_LITERAL, NULL); if(woe_id) fsf->emit_triple(fcs->data, place_bnode, FLICKCURL_TERM_TYPE_BLANK, PLACES_NS, "placeid", woe_id, FLICKCURL_TERM_TYPE_LITERAL, NULL); if(url) fsf->emit_triple(fcs->data, place_bnode, FLICKCURL_TERM_TYPE_BLANK, PLACES_NS, "url", url, FLICKCURL_TERM_TYPE_RESOURCE, NULL); } } /* generate triples from sizes */ if(sizes) { for(i=0; sizes[i]; i++) { flickcurl_size* size=sizes[i]; char buf[10]; int is_photo; const char* sizePredicate; const char* sizeClass; is_photo=(!strcmp(size->media, "photo")); sizePredicate=is_photo ? "photo" : "video"; sizeClass=is_photo ? FOAF_NS "Image" : FLICKR_NS "Video"; fsf->emit_triple(fcs->data, photo->uri, FLICKCURL_TERM_TYPE_RESOURCE, FLICKR_NS, sizePredicate, size->source, FLICKCURL_TERM_TYPE_RESOURCE, NULL); fsf->emit_triple(fcs->data, size->source, FLICKCURL_TERM_TYPE_RESOURCE, RDF_NS, "type", sizeClass, FLICKCURL_TERM_TYPE_RESOURCE, NULL); if(size->label) fsf->emit_triple(fcs->data, size->source, FLICKCURL_TERM_TYPE_RESOURCE, RDFS_NS, "label", size->label, FLICKCURL_TERM_TYPE_LITERAL, NULL); sprintf(buf, "%d", size->width); fsf->emit_triple(fcs->data, size->source, FLICKCURL_TERM_TYPE_RESOURCE, FLICKR_NS, "width", buf, FLICKCURL_TERM_TYPE_LITERAL, XSD_NS "integer"); sprintf(buf, "%d", size->height); fsf->emit_triple(fcs->data, size->source, FLICKCURL_TERM_TYPE_RESOURCE, FLICKR_NS, "height", buf, FLICKCURL_TERM_TYPE_LITERAL, XSD_NS "integer"); } flickcurl_free_sizes(sizes); } if(nspaces) free_nspaces(nspaces); if(fsf->emit_finish) fsf->emit_finish(fcs->data); return 0; }
int main(int argc, char *argv[]) { flickcurl *fc; flickcurl_photo *photo; flickcurl_photo_field_type field_type; int i; flickcurl_init(); /* optional static initialising of resources */ fc = flickcurl_new(); #if defined(WIN32) && defined(_MSC_VER) flickcurl_config_read_ini(fc, ".flickcurl.conf", "flickr", fc, flickcurl_config_var_handler); #else /* Set configuration explicitly: ... */ flickcurl_set_oauth_client_key(fc, "..."); flickcurl_set_oauth_client_secret(fc, "..."); flickcurl_set_oauth_token(fc, "..."); flickcurl_set_oauth_token_secret(fc, "..."); /* or could read from an INI config file like this: */ /* flickcurl_config_read_ini(fc, "/home/user/.flickcurl.conf", "flickr", fc, flickcurl_config_var_handler); */ #endif /* Pick your own photo ID */ #define PHOTO_ID "123456789" photo = flickcurl_photos_getInfo(fc, PHOTO_ID); if(!photo) { fprintf(stderr, "flickcurl_photos_getInfo(%s) failed\n", PHOTO_ID); } else { for(field_type = 0; field_type <= PHOTO_FIELD_LAST; field_type++) { flickcurl_field_value_type datatype = photo->fields[field_type].type; if(datatype != VALUE_TYPE_NONE) fprintf(stderr, "field %s (%d) with %s value: '%s' / %d\n", flickcurl_get_photo_field_label(field_type), (int)field_type, flickcurl_get_field_value_type_label(datatype), photo->fields[field_type].string, photo->fields[field_type].integer); } for(i = 0; i < photo->tags_count; i++) { flickcurl_tag* tag=photo->tags[i]; fprintf(stderr, "%d) %s tag: id %s author ID %s name %s raw '%s' cooked '%s' count %d\n", i, (tag->machine_tag ? "machine" : "regular"), tag->id, tag->author, (tag->authorname ? tag->authorname : "(Unknown)"), tag->raw, tag->cooked, tag->count); } flickcurl_free_photo(photo); } flickcurl_free(fc); flickcurl_finish(); /* optional static free of resources */ return 0; }