blob: 7320648d01d85001554a7af68ada6bdfa5bf0f4f [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.streams.instagram.serializer.util;
import org.apache.streams.exceptions.ActivityConversionException;
import org.apache.streams.exceptions.ActivitySerializerException;
import org.apache.streams.instagram.pojo.*;
import org.apache.streams.pojo.extensions.ExtensionUtil;
import org.apache.streams.pojo.json.Activity;
import org.apache.streams.pojo.json.ActivityObject;
import org.apache.streams.pojo.json.Image;
import org.apache.streams.pojo.json.Provider;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 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
* @param activity the target of the updates. Will receive all values from the tweet.
* @throws ActivityConversionException ActivityConversionException
*/
public static void updateActivity(Media item, Activity activity) throws ActivityConversionException {
activity.setActor(buildActor(item));
activity.setVerb("post");
if (item.getCreatedTime() != null) {
activity.setPublished(new DateTime(Long.parseLong(item.getCreatedTime()) * 1000));
}
activity.setId(formatId(activity.getVerb(),
Optional.ofNullable(item.getId()).orElse(null)));
activity.setProvider(getProvider());
activity.setUrl(item.getLink());
activity.setObject(buildActivityObject(item));
if (item.getCaption() != null) {
activity.setContent(item.getCaption().getText());
}
addInstagramExtensions(activity, item);
}
/**
* Updates the given Activity object with the values from the item
* @param item the object to use as the source
* @param activity the target of the updates. Will receive all values from the tweet.
* @throws ActivitySerializerException ActivitySerializerException
*/
public static void updateActivity(UserInfo item, Activity activity) throws ActivitySerializerException {
activity.setActor(buildActor(item));
activity.setId(null);
activity.setProvider(getProvider());
}
/**
* Builds an Actor object given a UserInfo object.
* @param item UserInfo item
* @return Actor object
*/
public static ActivityObject buildActor(UserInfo item) {
ActivityObject actor = new ActivityObject();
try {
Image image = new Image();
image.setUrl(item.getProfilePicture());
UserInfoCounts counts = item.getCounts();
Map<String, Object> extensions = new HashMap<>();
extensions.put("followers", counts.getFollowedBy());
extensions.put("follows", counts.getFollows());
extensions.put("screenName", item.getUsername());
extensions.put("posts", counts.getMedia());
actor.setId(formatId(String.valueOf(item.getId())));
actor.setImage(image);
actor.setDisplayName(item.getFullName());
actor.setSummary(item.getBio());
actor.setUrl(item.getWebsite());
actor.setAdditionalProperty("handle", item.getUsername());
actor.setAdditionalProperty("extensions", extensions);
} catch (Exception ex) {
LOGGER.error("Exception trying to build actor object: {}", ex.getMessage());
}
return actor;
}
/**
* Builds the actor.
* @param item Media item
* @return a valid ActivityObject
*/
public static ActivityObject buildActor(Media item) {
ActivityObject actor = new ActivityObject();
try {
Image image = new Image();
image.setUrl(item.getUser().getProfilePicture());
Map<String, Object> extensions = new HashMap<>();
extensions.put("screenName", item.getUser().getUsername());
actor.setDisplayName(item.getUser().getFullName());
actor.setSummary(item.getUser().getBio());
actor.setUrl(item.getUser().getWebsite());
actor.setId(formatId(String.valueOf(item.getUser().getId())));
actor.setImage(image);
actor.setAdditionalProperty("extensions", extensions);
actor.setAdditionalProperty("handle", item.getUser().getUsername());
} catch (Exception ex) {
LOGGER.error("Exception trying to build actor object: {}", ex.getMessage());
}
return actor;
}
/**
* Builds the object.
* @param item the item
* @return a valid Activity Object
*/
public static ActivityObject buildActivityObject(Media item) {
ActivityObject actObj = new ActivityObject();
actObj.setObjectType(item.getType().toString());
actObj.setAttachments(buildActivityObjectAttachments(item));
Image standardResolution = new Image();
if (item.getType().equals("image") && item.getImages() != null) {
MediaItem standardResolutionData = item.getImages().getStandardResolution();
standardResolution.setHeight(standardResolutionData.getHeight().longValue());
standardResolution.setWidth(standardResolutionData.getWidth().longValue());
standardResolution.setUrl(standardResolutionData.getUrl());
} else if (item.getType().equals("video") && item.getVideos() != null) {
MediaItem standardResolutionData = item.getVideos().getStandardResolution();
standardResolution.setHeight(standardResolutionData.getHeight().longValue());
standardResolution.setWidth(standardResolutionData.getWidth().longValue());
standardResolution.setUrl(standardResolutionData.getUrl());
}
actObj.setImage(standardResolution);
return actObj;
}
/**
* Builds all of the attachments associated with a Media object.
*
* @param item item
* @return result
*/
public static List<ActivityObject> buildActivityObjectAttachments(Media item) {
List<ActivityObject> attachments = new ArrayList<>();
addImageObjects(attachments, item);
addVideoObjects(attachments, item);
return attachments;
}
/**
* Adds any image objects to the attachment field.
* @param attachments attachments
* @param item item
*/
public static void addImageObjects(List<ActivityObject> attachments, Media item) {
Images images = item.getImages();
if (images != null) {
try {
MediaItem thumbnail = images.getThumbnail();
MediaItem lowResolution = images.getLowResolution();
ActivityObject thumbnailObject = new ActivityObject();
Image thumbnailImage = new Image();
thumbnailImage.setUrl(thumbnail.getUrl());
thumbnailImage.setHeight(thumbnail.getHeight().longValue());
thumbnailImage.setWidth(thumbnail.getWidth().longValue());
thumbnailObject.setImage(thumbnailImage);
thumbnailObject.setObjectType("image");
ActivityObject lowResolutionObject = new ActivityObject();
Image lowResolutionImage = new Image();
lowResolutionImage.setUrl(lowResolution.getUrl());
lowResolutionImage.setHeight(lowResolution.getHeight().longValue());
lowResolutionImage.setWidth(lowResolution.getWidth().longValue());
lowResolutionObject.setImage(lowResolutionImage);
lowResolutionObject.setObjectType("image");
attachments.add(thumbnailObject);
attachments.add(lowResolutionObject);
} catch (Exception ex) {
LOGGER.error("Failed to add image objects: {}", ex.getMessage());
}
}
}
/**
* Adds any video objects to the attachment field.
* @param attachments attachments
* @param item item
*/
public static void addVideoObjects(List<ActivityObject> attachments, Media item) {
Videos videos = item.getVideos();
if (videos != null) {
try {
MediaItem lowResolutionVideo = videos.getLowResolution();
ActivityObject lowResolutionVideoObject = new ActivityObject();
Image lowResolutionVideoImage = new Image();
lowResolutionVideoImage.setUrl(lowResolutionVideo.getUrl());
lowResolutionVideoImage.setHeight(lowResolutionVideo.getHeight().longValue());
lowResolutionVideoImage.setWidth(lowResolutionVideo.getWidth().longValue());
lowResolutionVideoObject.setImage(lowResolutionVideoImage);
lowResolutionVideoObject.setObjectType("video");
attachments.add(lowResolutionVideoObject);
} catch (Exception ex) {
LOGGER.error("Failed to add video objects: {}", ex.getMessage());
}
}
}
/**
* Gets the links from the Instagram event.
* @param item the object to use as the source
* @return a list of links corresponding to the expanded URL
*/
public static List<String> getLinks(Media item) {
return new ArrayList<>();
}
/**
* Adds the location extension and populates with the instagram data.
* @param activity the Activity object to update
* @param item the object to use as the source
*/
public static void addLocationExtension(Activity activity, Media item) {
Map<String, Object> extensions = ExtensionUtil.getInstance().ensureExtensions(activity);
if (item.getLocation() != null) {
Map<String, Object> coordinates = new HashMap<>();
coordinates.put("type", "Point");
coordinates.put("coordinates", "[" + item.getLocation().getLongitude() + "," + item.getLocation().getLatitude() + "]");
extensions.put("coordinates", coordinates);
}
}
/**
* Gets the common instagram {@link Provider} object.
* @return a provider object representing Instagram
*/
public static Provider getProvider() {
Provider provider = new Provider();
provider.setId("id:providers:instagram");
provider.setDisplayName("Instagram");
return provider;
}
/**
* Formats the ID to conform with the Apache Streams activity ID convention
* @param idparts the parts of the ID to join
* @return a valid Activity ID in format "id:instagram:part1:part2:...partN"
*/
public static String formatId(String... idparts) {
return String.join(":",
Stream.concat(Arrays.stream(new String[]{"id:instagram"}), Arrays.stream(idparts)).collect(Collectors.toList()));
}
/**
* Takes various parameters from the instagram object that are currently not part of the
* activity schema and stores them in a generic extensions attribute.
* @param activity Activity activity
* @param item Media item
*/
public static void addInstagramExtensions(Activity activity, Media item) {
Map<String, Object> extensions = ExtensionUtil.getInstance().ensureExtensions(activity);
addLocationExtension(activity, item);
if (item.getLikes() != null) {
Map<String, Object> likes = new HashMap<>();
likes.put("count", item.getLikes().getCount());
extensions.put("likes", likes);
}
if (item.getComments() != null) {
Map<String, Object> comments = new HashMap<>();
comments.put("count", item.getComments().getCount());
extensions.put("comments", comments);
}
extensions.put("hashtags", item.getTags());
Comments comments = item.getComments();
String commentsConcat = "";
if (comments != null) {
for (Comment comment : comments.getData()) {
commentsConcat += " " + comment.getText();
}
}
if (item.getCaption() != null) {
commentsConcat += " " + item.getCaption().getText();
}
extensions.put("keywords", commentsConcat);
}
}