[tracker/miner-flickr: 22/24] tracker-miner-flickr: Writeback for tags on photos



commit 149d507dd94ce14d3ba2da250e74b8c18fd96152
Author: Adrien Bustany <abustany gnome org>
Date:   Fri Mar 26 13:00:07 2010 -0300

    tracker-miner-flickr: Writeback for tags on photos
    
    This commit implements the writeback functionality for tags on photos. Tag
    adds/removal will be propagated to Flickr.

 src/miners/flickr/tracker-miner-flickr.vala |  133 ++++++++++++++++++++++++++-
 1 files changed, 130 insertions(+), 3 deletions(-)
---
diff --git a/src/miners/flickr/tracker-miner-flickr.vala b/src/miners/flickr/tracker-miner-flickr.vala
index b026ccb..e174c36 100644
--- a/src/miners/flickr/tracker-miner-flickr.vala
+++ b/src/miners/flickr/tracker-miner-flickr.vala
@@ -34,6 +34,8 @@ public class MinerFlickr : Tracker.MinerWeb {
 	private static const string FLICKR_REST_URL = "http://api.flickr.com/services/rest/";;
 	private static const string FLICKR_PHOTOSET_URL = "http://www.flickr.com/photos/%s/sets/%s";;
 	private static const string FLICKR_PHOTO_URL = "http://farm%s.static.flickr.com/%s/%s_%s.jpg";;
+	private static const string NMM_PHOTO = "http://www.tracker-project.org/temp/nmm#Photo";;
+	private static const string NAO_TAG = "http://www.semanticdesktop.org/ontologies/2007/08/15/nao#Tag";;
 
 	/* Values taken from the EXIF spec */
 	private enum ExifTag {
@@ -389,6 +391,108 @@ public class MinerFlickr : Tracker.MinerWeb {
 		}
 	}
 
+	private void add_tags (string photo_id, string[] tags) {
+		Rest.ProxyCall tag_call;
+
+		tag_call = rest.new_call ();
+		tag_call.add_params ("method", "flickr.photos.addTags",
+		                     "photo_id", photo_id,
+		                     "tags", string.joinv (",", tags));
+
+		try {
+			run_call (tag_call);
+		} catch (Error call_error) {
+			warning ("Couldn't add tags for photo %s: %s", photo_id, call_error.message);
+			return;
+		}
+	}
+
+	private void remove_tag (string tag_id) {
+		Rest.ProxyCall tag_call;
+
+		tag_call = rest.new_call ();
+		tag_call.add_params ("method", "flickr.photos.removeTag",
+		                     "tag_id", tag_id);
+
+		try {
+			run_call (tag_call);
+		} catch (Error call_error) {
+			warning ("Couldn't remove tag: %s", call_error.message);
+			return;
+		}
+	}
+
+	private async void writeback_photo (string uri) {
+		weak PtrArray results;
+		weak string[][] triples;
+		string photo_id;
+		string[] local_tags = {};
+		HashTable<string, string> flickr_tags = new HashTable<string, string> (str_hash, str_equal);
+		string[] tags_to_add = {};
+		string[] tags_to_remove = {};
+		Rest.ProxyCall tag_call;
+		Rest.XmlNode root_node;
+		Rest.XmlNode tag_node;
+
+		try {
+			results = yield execute_sparql (("select ?photo_id ?tag where { <%s> nie:dataSource <%s> ;"
+			                                                               +    "nao:identifier ?photo_id ;"
+			                                                               +    "nao:hasTag ?t ."
+			                                                               + "?t nao:prefLabel ?tag }").printf (uri, DATASOURCE_URN));
+		} catch (Error tracker_error) {
+			warning ("Tracker error when doing writeback for photo %s: %s", uri, tracker_error.message);
+			return;
+		}
+
+		if (results.len == 0) {
+			return;
+		}
+
+		triples = (string[][])results.pdata;
+		photo_id = triples[0][0];
+
+		for (uint i = 0 ; i < results.len ; ++i) {
+			local_tags += triples[i][1];
+		}
+
+		tag_call = rest.new_call ();
+		tag_call.add_params ("method", "flickr.tags.getListPhoto",
+		                     "photo_id", photo_id);
+		try {
+			root_node = run_call (tag_call);
+		} catch (Error get_tags_error) {
+			warning ("Couldn't get tags for photo %s: %s", uri, get_tags_error.message);
+			return;
+		}
+
+		tag_node = root_node.find ("tags").find ("tag");
+
+		while (tag_node != null) {
+			flickr_tags.insert (tag_node.get_attr ("raw"),
+			                    tag_node.get_attr ("id"));
+			tag_node = tag_node.next;
+		}
+
+		foreach (string local_tag in local_tags) {
+			if (flickr_tags.lookup (local_tag) == null) {
+				tags_to_add += local_tag;
+			}
+		}
+
+		foreach (weak string flickr_tag in flickr_tags.get_keys ()) {
+			if (array_search_str (flickr_tag, local_tags) == -1)
+				tags_to_remove += flickr_tags.lookup (flickr_tag);
+		}
+
+		add_tags (photo_id, tags_to_add);
+
+		foreach (string tag in tags_to_remove)
+			remove_tag (tag);
+	}
+
+	private void writeback_tag (string uri) {
+	}
+
 	private double ratioToDouble (string ratio) {
 		string[] tokens = ratio.split ("/");
         if (tokens[1].to_int () == 0) {
@@ -398,6 +502,15 @@ public class MinerFlickr : Tracker.MinerWeb {
         return (tokens[0].to_int () * 1.0) / (tokens[1].to_int ());
 	}
 
+	private int array_search_str (string needle, string[] haystack) {
+		for (int i = 0 ; i < haystack.length ; ++i) {
+			if (haystack[i] == needle)
+				return i;
+		}
+
+		return -1;
+	}
+
 	private void sign_call (Rest.ProxyCall call) {
 		StringBuilder signature;
 		HashTable<string, string> parameters;
@@ -466,8 +579,8 @@ public class MinerFlickr : Tracker.MinerWeb {
 		this.frob = frob_node.content;
 
 		api_signature = Checksum.compute_for_string (ChecksumType.MD5,
-		                                            SHARED_SECRET + "api_key" + API_KEY + "frob" + this.frob + "permsread");
-		url = FLICKR_AUTH_URL + "?api_key=" + API_KEY + "&perms=read&frob=" + this.frob + "&api_sig=" + api_signature;
+		                                             SHARED_SECRET + "api_key" + API_KEY + "frob" + this.frob + "permswrite");
+		url = FLICKR_AUTH_URL + "?api_key=" + API_KEY + "&perms=write&frob=" + this.frob + "&api_sig=" + api_signature;
 
 		association_data.insert ("url", url);
 
@@ -571,8 +684,22 @@ public class MinerFlickr : Tracker.MinerWeb {
 	public override void writeback (HashTable properties)
 	{
 		List<weak string> uris = (List<weak string>)properties.get_keys ();
+		weak string[] rdf_classes;
+
 		foreach (string uri in uris) {
-			message ("writeback for uri %s", uri);
+			rdf_classes = (string[])properties.lookup (uri);
+
+			for (uint i = 0; rdf_classes[i] != null; i++) {
+				if (rdf_classes[i] == NMM_PHOTO) {
+					writeback_photo (uri);
+					return;
+				}
+
+				if (rdf_classes[i] == NAO_TAG) {
+					writeback_tag (uri);
+					return;
+				}
+			}
 		}
 	}
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]