package org.gcube.gcat.social; import java.io.StringWriter; import java.net.HttpURLConnection; import java.util.ArrayList; import java.util.List; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import org.gcube.com.fasterxml.jackson.databind.JsonNode; import org.gcube.com.fasterxml.jackson.databind.ObjectMapper; import org.gcube.com.fasterxml.jackson.databind.node.ArrayNode; import org.gcube.com.fasterxml.jackson.databind.node.ObjectNode; import org.gcube.common.authorization.utils.manager.SecretManager; import org.gcube.common.authorization.utils.socialservice.SocialService; import org.gcube.common.gxhttp.request.GXHTTPStringRequest; import org.gcube.gcat.persistence.ckan.CKANInstance; import org.gcube.gcat.persistence.ckan.CKANUserCache; import org.gcube.gcat.utils.Constants; import org.gcube.gcat.utils.HTTPUtility; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Luca Frosini (ISTI - CNR) */ public class SocialPost extends Thread { private static final Logger logger = LoggerFactory.getLogger(SocialPost.class); public static final String ITEM_URL = "Item URL"; // https://wiki.gcube-system.org/gcube/Social_Networking_Service#Write_application_post_2 protected static final String SOCIAL_SERVICE_WRITE_APPLICATION_POST_PATH = "/2/posts/write-post-app"; // String.format(NOTIFICATION_MESSAGE, fullName, title, url) protected static final String NOTIFICATION_MESSAGE = "%s just published the item \"%s\"\n" + "Please find it at %s\n"; protected static final String SOCIAL_POST_TEXT_KEY = "text"; protected static final String SOCIAL_POST_ENABLE_NOTIFICATION_KEY = "enable_notification"; protected static final String SOCIAL_POST_RESPONSE_SUCCESS_KEY = "success"; protected static final String SOCIAL_POST_RESPONSE_MESSAGE_KEY = "message"; protected final ObjectMapper objectMapper; protected String itemID; protected String itemURL; protected String itemTitle; protected List tags; protected Boolean notification; public SocialPost() throws Exception { super(); this.objectMapper = new ObjectMapper(); } public String getItemID() { return itemID; } public void setItemID(String itemID) { this.itemID = itemID; } public String getItemURL() { return itemURL; } public void setItemURL(String itemURL) { this.itemURL = itemURL; } public String getItemTitle() { return itemTitle; } public void setItemTitle(String itemTitle) { this.itemTitle = itemTitle; } public List getTags() { return tags; } public void setTags(List tags) { this.tags = tags; } public void setTags(ArrayNode tags) { this.tags = new ArrayList<>(); if(tags != null && tags.size() > 0) { for(int i = 0; i < tags.size(); i++) { JsonNode jsonNode = tags.get(i); String tagName = ""; if(jsonNode.has("display_name")) { tagName = jsonNode.get("display_name").asText(); } else { tagName = jsonNode.get("name").asText(); } this.tags.add(tagName); } } } public Boolean isNotification() { return notification; } public void setNotification(Boolean notification) { this.notification = notification; } @Override public void run() { try { CKANInstance instance = CKANInstance.getInstance(); if(!instance.isSocialPostEnabled()) { logger.info("Social Post are disabled in the context {}", SecretManager.instance.get().getContext()); return; } logger.info("Going to send Social Post about the Item {} available at {}", itemID, itemURL); boolean notifyUsers = instance.isNotificationToUsersEnabled(); if(notification != null) { if(notifyUsers) { notifyUsers = notifyUsers && notification; }else { notifyUsers = notification; } } // write notification post sendSocialPost(notifyUsers); } catch(Exception e) { logger.error("Error while executing post creation actions", e); } } public void sendSocialPost(boolean notifyUsers) { try { String fullName = CKANUserCache.getCurrrentCKANUser().getNameSurname(); String basePath = SocialService.getSocialService().getServiceBasePath(); if(basePath == null) { logger.info("Unable to write a post because there is no social networking service available"); return; } basePath = basePath.endsWith("/") ? basePath : basePath + "/"; StringWriter messageWriter = new StringWriter(); messageWriter.append(String.format(NOTIFICATION_MESSAGE, fullName, itemTitle, itemURL)); for(String tag : tags) { tag = tag.trim(); tag = tag.replaceAll(" ", "_").replace("_+", "_"); if(tag.endsWith("_")) { tag = tag.substring(0, tag.length() - 1); } messageWriter.append("#"); messageWriter.append(tag); messageWriter.append(" "); } String message = messageWriter.toString(); logger.debug("The post that is going to be written is\n{}", message); ObjectNode objectNode = objectMapper.createObjectNode(); objectNode.put(SOCIAL_POST_TEXT_KEY, message); objectNode.put(SOCIAL_POST_ENABLE_NOTIFICATION_KEY, notifyUsers); // Do not use ApplicationMode class here because is a thread and change the current token could impact // on the other threads. GXHTTPStringRequest gxhttpStringRequest = GXHTTPStringRequest.newRequest(basePath); gxhttpStringRequest.from(Constants.CATALOGUE_NAME); gxhttpStringRequest.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON); gxhttpStringRequest.setSecurityToken(Constants.getCatalogueSecurityToken()); gxhttpStringRequest.path(SOCIAL_SERVICE_WRITE_APPLICATION_POST_PATH); HttpURLConnection httpURLConnection = gxhttpStringRequest.post(objectMapper.writeValueAsString(objectNode)); String ret = HTTPUtility.getResultAsString(httpURLConnection); JsonNode jsonNode = objectMapper.readTree(ret); if(jsonNode.get(SOCIAL_POST_RESPONSE_SUCCESS_KEY).asBoolean()) { logger.info("Post written : {}", message); } else { logger.info("Failed to write the post {}. Reason {}", message, jsonNode.get(SOCIAL_POST_RESPONSE_MESSAGE_KEY).asText()); } } catch(Exception e) { logger.error("Unable to send Social Post", e); } } }