Пример #1
0
/**
 * 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;
}
Пример #2
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;
}