You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@streams.apache.org by sb...@apache.org on 2014/07/21 17:45:01 UTC
[15/47] git commit: STREAMS-122 | Updated the InstagramActivityUtil
class to fully map Instagram MediaFeedData objects to Activities. Updated
tests so that this deserialization and mapping can be tested
STREAMS-122 | Updated the InstagramActivityUtil class to fully map Instagram MediaFeedData objects to Activities. Updated tests so that this deserialization and mapping can be tested
Project: http://git-wip-us.apache.org/repos/asf/incubator-streams/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-streams/commit/11636535
Tree: http://git-wip-us.apache.org/repos/asf/incubator-streams/tree/11636535
Diff: http://git-wip-us.apache.org/repos/asf/incubator-streams/diff/11636535
Branch: refs/heads/STREAMS-46
Commit: 116365355dad985da52092c85378b5bd7497e907
Parents: 7b301ce
Author: Robert Douglas <rd...@w2odigital.com>
Authored: Tue Jul 1 17:12:57 2014 -0500
Committer: Robert Douglas <rd...@w2odigital.com>
Committed: Tue Jul 1 17:12:57 2014 -0500
----------------------------------------------------------------------
streams-contrib/pom.xml | 1 +
.../InstagramJsonActivitySerializer.java | 22 ++-
.../serializer/util/InstagramActivityUtil.java | 170 ++++++++++++++++---
.../test/InstagramActivitySerDeTest.java | 24 ++-
.../src/test/resources/testMediaFeedObjects.txt | 2 +
5 files changed, 181 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/11636535/streams-contrib/pom.xml
----------------------------------------------------------------------
diff --git a/streams-contrib/pom.xml b/streams-contrib/pom.xml
index 620f68e..699274e 100644
--- a/streams-contrib/pom.xml
+++ b/streams-contrib/pom.xml
@@ -47,6 +47,7 @@
<module>streams-amazon-aws</module>
<!--<module>streams-processor-lucene</module>-->
<!--<module>streams-processor-tika</module>-->
+ <module>streams-provider-instagram</module>
<module>streams-processor-json</module>
<module>streams-processor-urls</module>
<module>streams-provider-datasift</module>
http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/11636535/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/serializer/InstagramJsonActivitySerializer.java
----------------------------------------------------------------------
diff --git a/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/serializer/InstagramJsonActivitySerializer.java b/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/serializer/InstagramJsonActivitySerializer.java
index 8d92641..c5bbdf1 100644
--- a/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/serializer/InstagramJsonActivitySerializer.java
+++ b/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/serializer/InstagramJsonActivitySerializer.java
@@ -18,14 +18,21 @@
package org.apache.streams.instagram.serializer;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.NotImplementedException;
import org.apache.streams.data.ActivitySerializer;
import org.apache.streams.exceptions.ActivitySerializerException;
+import org.apache.streams.jackson.StreamsJacksonMapper;
import org.apache.streams.pojo.json.Activity;
+import org.jinstagram.entity.users.feed.MediaFeedData;
+import java.io.IOException;
import java.io.Serializable;
import java.util.List;
+import static org.apache.streams.instagram.serializer.util.InstagramActivityUtil.updateActivity;
+
public class InstagramJsonActivitySerializer implements ActivitySerializer<String>, Serializable
{
@@ -46,9 +53,20 @@ public class InstagramJsonActivitySerializer implements ActivitySerializer<Strin
@Override
public Activity deserialize(String serialized) throws ActivitySerializerException {
- Activity activity = null;
+ ObjectMapper mapper = StreamsJacksonMapper.getInstance();
+ MediaFeedData mediaFeedData = null;
+
+ try {
+ mediaFeedData = mapper.readValue(serialized, MediaFeedData.class);
+ } catch (JsonProcessingException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ Activity activity = new Activity();
- // implement
+ updateActivity(mediaFeedData, activity);
return activity;
}
http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/11636535/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/serializer/util/InstagramActivityUtil.java
----------------------------------------------------------------------
diff --git a/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/serializer/util/InstagramActivityUtil.java b/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/serializer/util/InstagramActivityUtil.java
index e71c43e..0561ba7 100644
--- a/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/serializer/util/InstagramActivityUtil.java
+++ b/streams-contrib/streams-provider-instagram/src/main/java/org/apache/streams/instagram/serializer/util/InstagramActivityUtil.java
@@ -19,16 +19,21 @@
package org.apache.streams.instagram.serializer.util;
-import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.base.Joiner;
+import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import org.apache.streams.exceptions.ActivitySerializerException;
-import org.apache.streams.pojo.json.Activity;
-import org.apache.streams.pojo.json.ActivityObject;
-import org.apache.streams.pojo.json.Actor;
-import org.apache.streams.pojo.json.Provider;
+import org.apache.streams.pojo.json.*;
+import org.jinstagram.entity.common.ImageData;
+import org.jinstagram.entity.common.Images;
+import org.jinstagram.entity.common.VideoData;
+import org.jinstagram.entity.common.Videos;
import org.jinstagram.entity.users.feed.MediaFeedData;
+import org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -39,7 +44,7 @@ import static org.apache.streams.data.util.ActivityUtil.ensureExtensions;
* Provides utilities for working with Activity objects within the context of Instagram
*/
public class InstagramActivityUtil {
-
+ private static final Logger LOGGER = LoggerFactory.getLogger(InstagramActivityUtil.class);
/**
* Updates the given Activity object with the values from the item
* @param item the object to use as the source
@@ -47,7 +52,22 @@ public class InstagramActivityUtil {
* @throws ActivitySerializerException
*/
public static void updateActivity(MediaFeedData item, Activity activity) throws ActivitySerializerException {
+ activity.setActor(buildActor(item));
+ activity.setPublished(new DateTime(Long.parseLong(item.getCreatedTime()) * 1000));
+
+ activity.setId(formatId(activity.getVerb(),
+ Optional.fromNullable(
+ item.getId())
+ .orNull()));
+
+ activity.setProvider(getProvider());
+ activity.setUrl(item.getLink());
+ activity.setObject(buildActivityObject(item));
+ if(item.getCaption() != null)
+ activity.setContent(item.getCaption().getText());
+
+ addInstagramExtensions(activity, item);
}
/**
@@ -57,6 +77,18 @@ public class InstagramActivityUtil {
*/
public static Actor buildActor(MediaFeedData item) {
Actor actor = new Actor();
+
+ Image image = new Image();
+ image.setUrl(item.getUser().getProfilePictureUrl());
+
+ Map<String, Object> extensions = new HashMap<String, Object>();
+ extensions.put("screenName", item.getUser().getUserName());
+
+ actor.setId(formatId(String.valueOf(item.getUser().getId())));
+ actor.setImage(image);
+ actor.setAdditionalProperty("extensions", extensions);
+ actor.setAdditionalProperty("handle", item.getUser().getUserName());
+
return actor;
}
@@ -67,18 +99,90 @@ public class InstagramActivityUtil {
*/
public static ActivityObject buildActivityObject(MediaFeedData item) {
ActivityObject actObj = new ActivityObject();
+
+ actObj.setObjectType(item.getType());
+ actObj.setAttachments(buildActivityObjectAttachments(item));
+
return actObj;
}
+ /**
+ * Builds all of the attachments associated with a MediaFeedData object
+ *
+ * @param item
+ * @return
+ */
+ public static List<ActivityObject> buildActivityObjectAttachments(MediaFeedData item) {
+ List<ActivityObject> attachments = new ArrayList<ActivityObject>();
+
+ addImageObjects(attachments, item);
+ addVideoObjects(attachments, item);
+
+ return attachments;
+ }
/**
- * Updates the content, and associated fields, with those from the given tweet
- * @param activity the target of the updates. Will receive all values from the tweet.
- * @param item the object to use as the source
- * @param verb the verb for the given activity's type
+ * Adds any image objects to the attachment field
+ * @param attachments
+ * @param item
+ */
+ public static void addImageObjects(List<ActivityObject> attachments, MediaFeedData item) {
+ Images images = item.getImages();
+
+ if(images != null) {
+ try {
+ ImageData thumbnail = images.getThumbnail();
+ ImageData lowResolution = images.getLowResolution();
+
+ ActivityObject thumbnailObject = new ActivityObject();
+ Image thumbnailImage = new Image();
+ thumbnailImage.setUrl(thumbnail.getImageUrl());
+ thumbnailImage.setHeight((double) thumbnail.getImageHeight());
+ thumbnailImage.setWidth((double) thumbnail.getImageWidth());
+ thumbnailObject.setImage(thumbnailImage);
+ thumbnailObject.setObjectType("image");
+
+ ActivityObject lowResolutionObject = new ActivityObject();
+ Image lowResolutionImage = new Image();
+ lowResolutionImage.setUrl(lowResolution.getImageUrl());
+ lowResolutionImage.setHeight((double) lowResolution.getImageHeight());
+ lowResolutionImage.setWidth((double) lowResolution.getImageWidth());
+ lowResolutionObject.setImage(lowResolutionImage);
+ lowResolutionObject.setObjectType("image");
+
+ attachments.add(thumbnailObject);
+ attachments.add(lowResolutionObject);
+ } catch (Exception e) {
+ LOGGER.error("Failed to add image objects: {}", e.getMessage());
+ }
+ }
+ }
+
+ /**
+ * Adds any video objects to the attachment field
+ * @param attachments
+ * @param item
*/
- public static void updateActivityContent(Activity activity, MediaFeedData item, String verb) {
+ public static void addVideoObjects(List<ActivityObject> attachments, MediaFeedData item) {
+ Videos videos = item.getVideos();
+
+ if(videos != null) {
+ try {
+ VideoData lowResolutionVideo = videos.getLowResolution();
+
+ ActivityObject lowResolutionVideoObject = new ActivityObject();
+ Image lowResolutionVideoImage = new Image();
+ lowResolutionVideoImage.setUrl(lowResolutionVideo.getUrl());
+ lowResolutionVideoImage.setHeight((double) lowResolutionVideo.getHeight());
+ lowResolutionVideoImage.setWidth((double) lowResolutionVideo.getWidth());
+ lowResolutionVideoObject.setImage(lowResolutionVideoImage);
+ lowResolutionVideoObject.setObjectType("video");
+ attachments.add(lowResolutionVideoObject);
+ } catch (Exception e) {
+ LOGGER.error("Failed to add video objects: {}", e.getMessage());
+ }
+ }
}
/**
@@ -98,7 +202,14 @@ public class InstagramActivityUtil {
*/
public static void addLocationExtension(Activity activity, MediaFeedData item) {
Map<String, Object> extensions = ensureExtensions(activity);
- Map<String, Object> location = new HashMap<String, Object>();
+
+ if(item.getLocation() != null) {
+ Map<String, Object> coordinates = new HashMap<String, Object>();
+ coordinates.put("type", "Point");
+ coordinates.put("coordinates", "[" + item.getLocation().getLatitude() + "," + item.getLocation().getLongitude() + "]");
+
+ extensions.put("coordinates", coordinates);
+ }
}
@@ -112,15 +223,7 @@ public class InstagramActivityUtil {
provider.setDisplayName("Instagram");
return provider;
}
- /**
- * Adds the given Instagram event to the activity as an extension
- * @param activity the Activity object to update
- * @param event the Instagram event to add as the extension
- */
- public static void addInstagramExtension(Activity activity, ObjectNode event) {
- Map<String, Object> extensions = org.apache.streams.data.util.ActivityUtil.ensureExtensions(activity);
- extensions.put("instagram", event);
- }
+
/**
* Formats the ID to conform with the Apache Streams activity ID convention
* @param idparts the parts of the ID to join
@@ -138,5 +241,28 @@ public class InstagramActivityUtil {
*/
public static void addInstagramExtensions(Activity activity, MediaFeedData item) {
Map<String, Object> extensions = ensureExtensions(activity);
+
+ addLocationExtension(activity, item);
+
+ Map<String, Object> likes = new HashMap<String, Object>();
+ likes.put("count", item.getLikes().getCount());
+ extensions.put("likes", likes);
+
+ extensions.put("hashtags", item.getTags());
+
+ Image standardResolution = new Image();
+ if(item.getType() == "image" && item.getImages() != null) {
+ ImageData standardResolutionData = item.getImages().getStandardResolution();
+ standardResolution.setHeight((double)standardResolutionData.getImageHeight());
+ standardResolution.setWidth((double)standardResolutionData.getImageWidth());
+ standardResolution.setUrl(standardResolutionData.getImageUrl());
+ } else if(item.getType() == "video" && item.getVideos() != null) {
+ VideoData standardResolutionData = item.getVideos().getStandardResolution();
+ standardResolution.setHeight((double)standardResolutionData.getHeight());
+ standardResolution.setWidth((double)standardResolutionData.getWidth());
+ standardResolution.setUrl(standardResolutionData.getUrl());
+ }
+
+ extensions.put("image", standardResolution);
}
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/11636535/streams-contrib/streams-provider-instagram/src/test/java/org/apache/streams/twitter/test/InstagramActivitySerDeTest.java
----------------------------------------------------------------------
diff --git a/streams-contrib/streams-provider-instagram/src/test/java/org/apache/streams/twitter/test/InstagramActivitySerDeTest.java b/streams-contrib/streams-provider-instagram/src/test/java/org/apache/streams/twitter/test/InstagramActivitySerDeTest.java
index fcf5e81..075da80 100644
--- a/streams-contrib/streams-provider-instagram/src/test/java/org/apache/streams/twitter/test/InstagramActivitySerDeTest.java
+++ b/streams-contrib/streams-provider-instagram/src/test/java/org/apache/streams/twitter/test/InstagramActivitySerDeTest.java
@@ -20,11 +20,12 @@ package org.apache.streams.twitter.test;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang.StringUtils;
+import org.apache.streams.instagram.serializer.util.InstagramDeserializer;
import org.apache.streams.instagram.serializer.InstagramJsonActivitySerializer;
import org.apache.streams.jackson.StreamsJacksonMapper;
import org.apache.streams.pojo.json.Activity;
+import org.jinstagram.entity.users.feed.MediaFeedData;
import org.junit.Assert;
-import org.junit.Ignore;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -33,6 +34,7 @@ import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
+import static org.apache.streams.instagram.serializer.util.InstagramActivityUtil.updateActivity;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;
@@ -46,16 +48,11 @@ import static org.junit.Assert.assertThat;
public class InstagramActivitySerDeTest {
private final static Logger LOGGER = LoggerFactory.getLogger(InstagramActivitySerDeTest.class);
- private ObjectMapper mapper = StreamsJacksonMapper.getInstance();
- private InstagramJsonActivitySerializer instagramJsonActivitySerializer = new InstagramJsonActivitySerializer();
-
- // remove @Ignore after implementation
- @Ignore
@Test
- public void Tests()
- {
- InputStream is = InstagramActivitySerDeTest.class.getResourceAsStream("/test.txt");
+ public void Tests() {
+ InstagramDeserializer instagramDeserializer = new InstagramDeserializer("");
+ InputStream is = InstagramActivitySerDeTest.class.getResourceAsStream("/testMediaFeedObjects.txt");
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
@@ -66,13 +63,13 @@ public class InstagramActivitySerDeTest {
{
LOGGER.info("raw: {}", line);
- // convert to MediaFeedData?
- Activity activity = instagramJsonActivitySerializer.deserialize(line);
+ MediaFeedData mediaFeedData = instagramDeserializer.createObjectFromResponse(MediaFeedData.class, line);
- String activitystring = mapper.writeValueAsString(activity);
+ Activity activity = new Activity();
- LOGGER.info("activity: {}", activitystring);
+ LOGGER.info("activity: {}", activity.toString());
+ updateActivity(mediaFeedData, activity);
assertThat(activity, is(not(nullValue())));
assertThat(activity.getId(), is(not(nullValue())));
@@ -80,7 +77,6 @@ public class InstagramActivitySerDeTest {
assertThat(activity.getActor().getId(), is(not(nullValue())));
assertThat(activity.getVerb(), is(not(nullValue())));
assertThat(activity.getProvider(), is(not(nullValue())));
-
}
}
} catch( Exception e ) {
http://git-wip-us.apache.org/repos/asf/incubator-streams/blob/11636535/streams-contrib/streams-provider-instagram/src/test/resources/testMediaFeedObjects.txt
----------------------------------------------------------------------
diff --git a/streams-contrib/streams-provider-instagram/src/test/resources/testMediaFeedObjects.txt b/streams-contrib/streams-provider-instagram/src/test/resources/testMediaFeedObjects.txt
index e69de29..b62e599 100644
--- a/streams-contrib/streams-provider-instagram/src/test/resources/testMediaFeedObjects.txt
+++ b/streams-contrib/streams-provider-instagram/src/test/resources/testMediaFeedObjects.txt
@@ -0,0 +1,2 @@
+{ "attribution":null, "tags":[ ], "type":"image", "location":null, "comments":{ "count":0, "data":[ ] }, "filter":"X-Pro II", "created_time":"1404162054", "link":"http://instagram.com/p/p4ez__syJi/", "likes":{ "count":0, "data":[ ] }, "images":{ "low_resolution":{ "url":"http://scontent-a.cdninstagram.com/hphotos-xpa1/t51.2885-15/10518155_283164271863608_1534480525_a.jpg", "width":306, "height":306 }, "thumbnail":{ "url":"http://scontent-a.cdninstagram.com/hphotos-xpa1/t51.2885-15/10518155_283164271863608_1534480525_s.jpg", "width":150, "height":150 }, "standard_resolution":{ "url":"http://scontent-a.cdninstagram.com/hphotos-xpa1/t51.2885-15/10518155_283164271863608_1534480525_n.jpg", "width":640, "height":640 } }, "users_in_photo":[ ], "caption":{ "created_time":"1404162054", "text":"Testing streams", "from":{ "username":"ktsafford", "profile_picture":"http://images.ak.instagram.com/profiles/anonymousUser.jpg", "id":"1412068271", "full_name":"ktsafford" }, "id":"754488452958068751"
}, "user_has_liked":false, "id":"754488452387644002_1412068271", "user":{ "username":"ktsafford", "website":"", "profile_picture":"http://images.ak.instagram.com/profiles/anonymousUser.jpg", "full_name":"ktsafford", "bio":"", "id":"1412068271" } }
+{ "type":"image", "users_in_photo":[ { "user":{ "username":"kevin", "full_name":"Kevin S", "id":"3", "profile_picture":"..." }, "position":{ "x":0.315, "y":0.9111 } } ], "filter":"Walden", "tags":[ ], "comments":{ "data":[ { "created_time":"1279332030", "text":"Love the sign here", "from":{ "username":"mikeyk", "full_name":"Mikey Krieger", "id":"4", "profile_picture":"http://distillery.s3.amazonaws.com/profiles/profile_1242695_75sq_1293915800.jpg" }, "id":"8" }, { "created_time":"1279341004", "text":"Chilako taco", "from":{ "username":"kevin", "full_name":"Kevin S", "id":"3", "profile_picture":"..." }, "id":"3" } ], "count":2 }, "caption":null, "likes":{ "count":1, "data":[ { "username":"mikeyk", "full_name":"Mikeyk", "id":"4", "profile_picture":"..." } ] }, "link":"http://instagr.am/p/D/", "user":{ "username":"kevin", "full_name":"Kevin S", "profile_picture":"...", "bio":"...", "website":"...", "id":"3" }, "created_time":"1279340983", "images":{ "low_resolution":{ "url":"http://dis
tillery.s3.amazonaws.com/media/2010/07/16/4de37e03aa4b4372843a7eb33fa41cad_6.jpg", "width":306, "height":306 }, "thumbnail":{ "url":"http://distillery.s3.amazonaws.com/media/2010/07/16/4de37e03aa4b4372843a7eb33fa41cad_5.jpg", "width":150, "height":150 }, "standard_resolution":{ "url":"http://distillery.s3.amazonaws.com/media/2010/07/16/4de37e03aa4b4372843a7eb33fa41cad_7.jpg", "width":612, "height":612 } }, "id":"3", "location":null }