The moderation thread has been generalised form the implementation

This commit is contained in:
Luca Frosini 2021-11-26 12:27:31 +01:00
parent 06c4e5f539
commit c9b2a3b6f7
4 changed files with 154 additions and 80 deletions

View File

@ -0,0 +1,32 @@
package org.gcube.gcat.moderation.thread;
import org.gcube.gcat.api.CMItemStatus;
import org.gcube.gcat.utils.ContextUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class FakeModerationThread extends ModerationThread {
private static final Logger logger = LoggerFactory.getLogger(FakeModerationThread.class);
@Override
protected void postMessage(CMItemStatus cmItemStatus, String message) throws Exception {
logger.debug("gCat is sending a message to the {} for item '{}' (id={}). ItemStatus={}, Message=\"{}\"",
ModerationThread.class.getSimpleName(), itemName, itemID, cmItemStatus, message);
}
@Override
public void postUserMessage(CMItemStatus cmItemStatus, String userMessage) throws Exception {
logger.debug("{} is sending a message to the {} for item '{}' (id={}). ItemStatus={}, Message=\"{}\"",
ContextUtility.getUsername(), ModerationThread.class.getSimpleName(), itemName, itemID, cmItemStatus, userMessage);
}
@Override
protected void createModerationThread() throws Exception {
logger.debug("Creating {} for item '{}' (id={})", ModerationThread.class.getSimpleName(), itemName, itemID);
}
}

View File

@ -0,0 +1,87 @@
package org.gcube.gcat.moderation.thread;
import org.gcube.com.fasterxml.jackson.databind.ObjectMapper;
import org.gcube.gcat.api.CMItemStatus;
import org.gcube.gcat.persistence.ckan.CKANUser;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public abstract class ModerationThread {
protected String itemID;
protected String itemName;
protected CKANUser ckanUser;
protected ObjectMapper objectMapper;
public static ModerationThread getDefaultInstance() {
return new FakeModerationThread();
}
public ModerationThread() {
this.objectMapper = new ObjectMapper();
}
public void setItemCoordinates(String itemID, String itemName) {
this.itemID = itemID;
this.itemName = itemName;
}
public void setCKANUser(CKANUser ckanUser) {
this.ckanUser = ckanUser;
}
/**
* The message is sent as gCat
* @param cmItemStatus
* @param message
* @throws Exception
*/
protected abstract void postMessage(CMItemStatus cmItemStatus, String message) throws Exception;
/**
* The message is sent as User
* @param cmItemStatus
* @param userMessage
* @throws Exception
*/
public abstract void postUserMessage(CMItemStatus cmItemStatus, String userMessage) throws Exception;
protected abstract void createModerationThread() throws Exception ;
public void postItemCreated() throws Exception{
createModerationThread();
String username = ckanUser.getPortalUser().getNameSurname();
CMItemStatus cmItemStatus = CMItemStatus.PENDING;
String message = String.format("@**%s** has created the item with name '%s' (id='%s'). The item is now in **%s** state and must be moderated.",
username, itemName, itemID, cmItemStatus.getFancyValue());
postMessage(cmItemStatus, message);
}
public void postItemUpdated() throws Exception {
String username = ckanUser.getPortalUser().getNameSurname();
CMItemStatus cmItemStatus = CMItemStatus.PENDING;
String message = String.format("@**%s** has updated the item with name '%s' (id='%s'). The item is now in **%s** state and must be moderated.",
username, itemName, itemID, cmItemStatus.getFancyValue());
postMessage(cmItemStatus, message);
}
public void postItemRejected(String userMessage) throws Exception {
String username = ckanUser.getPortalUser().getNameSurname();
CMItemStatus cmItemStatus = CMItemStatus.REJECTED;
String message = String.format("@**%s** has **%s** the item with name '%s' (id='%s'). The author can delete the item or update it to try to meet moderators requests if any.",
username, cmItemStatus.getFancyValue(), itemName, itemID);
postMessage(cmItemStatus, message);
postUserMessage(cmItemStatus, userMessage);
}
public void postItemApproved(String userMessage) throws Exception{
String username = ckanUser.getPortalUser().getNameSurname();
CMItemStatus cmItemStatus = CMItemStatus.APPROVED;
String message = String.format("@**%s** has **%s** the item with name '%s' (id='%s'). The item is now available in the catalogue.",
username, cmItemStatus.getFancyValue(), itemName, itemID);
postMessage(cmItemStatus, message);
postUserMessage(cmItemStatus, userMessage);
}
}

View File

@ -5,13 +5,12 @@ import java.util.Set;
import javax.ws.rs.InternalServerErrorException;
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.gcat.api.CMItemStatus;
import org.gcube.gcat.api.GCatConstants;
import org.gcube.gcat.moderation.thread.ModerationThread;
import org.gcube.gcat.moderation.thread.zulip.ZulipResponse.Result;
import org.gcube.gcat.persistence.ckan.CKANUser;
import org.gcube.gcat.social.SocialUsers;
import org.gcube.gcat.utils.Constants;
import org.gcube.gcat.utils.ContextUtility;
@ -28,7 +27,7 @@ import io.taliox.zulip.calls.streams.PostCreateStream;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class ZulipStream {
public class ZulipStream extends ModerationThread {
private static final Logger logger = LoggerFactory.getLogger(ZulipStream.class);
@ -40,25 +39,18 @@ public class ZulipStream {
protected ZulipRestExecutor gCatZulipRestExecutor;
protected ZulipRestExecutor userZulipRestExecutor;
protected String itemID;
protected String itemName;
protected String streamName;
protected String streamDescription;
protected CKANUser ckanUser;
protected ObjectMapper objectMapper;
public ZulipStream() {
super();
}
protected ZulipRestExecutor getZulipRestExecutor() {
ZulipAuth zulipAuth = new ZulipAuth(ContextUtility.getUsername());
return new ZulipRestExecutor(zulipAuth.getEmail(), zulipAuth.getAPIKey(), zulipAuth.getSite());
}
public ZulipStream() {
this.objectMapper = new ObjectMapper();
}
public ZulipRestExecutor getGCatZulipRestExecutor() {
if(gCatZulipRestExecutor==null) {
ApplicationMode applicationMode = new ApplicationMode(Constants.getCatalogueApplicationToken());
@ -76,15 +68,6 @@ public class ZulipStream {
return userZulipRestExecutor;
}
public void setItemCoordinates(String itemID, String itemName) {
this.itemID = itemID;
this.itemName = itemName;
}
public void setCKANUser(CKANUser ckanUser) {
this.ckanUser = ckanUser;
}
protected String getStreamName() {
if(streamName==null) {
streamName = String.format("Item '%s' moderation", itemID);
@ -117,7 +100,8 @@ public class ZulipStream {
return zulipResponse;
}
public void create() throws Exception {
@Override
protected void createModerationThread() throws Exception {
ArrayNode streamsArrayNode = objectMapper.createArrayNode();
ObjectNode streamobjectNode = objectMapper.createObjectNode();
streamobjectNode.put("name", getStreamName());
@ -145,8 +129,6 @@ public class ZulipStream {
postCreateStream.setAnnounce(false);
executeZulipCall(gCatZulipRestExecutor, postCreateStream);
postItemCreated();
}
protected void postMessageToStream(ZulipRestExecutor zulipRestExecutor, CMItemStatus cmItemStatus, String message) throws Exception {
@ -155,42 +137,14 @@ public class ZulipStream {
executeZulipCall(zulipRestExecutor, postMessage);
}
public void postUserMessageToStream(CMItemStatus cmItemStatus, String message) throws Exception {
@Override
protected void postMessage(CMItemStatus cmItemStatus, String message) throws Exception {
postMessageToStream(getGCatZulipRestExecutor(), cmItemStatus, message);
}
@Override
public void postUserMessage(CMItemStatus cmItemStatus, String message) throws Exception {
postMessageToStream(getUserZulipRestExecutor(), cmItemStatus, message);
}
private void postItemCreated() throws Exception{
String username = ckanUser.getPortalUser().getNameSurname();
CMItemStatus cmItemStatus = CMItemStatus.PENDING;
String message = String.format("@**%s** has created the item with name '%s' (id='%s'). The item is now in **%s** state and must be moderated.",
username, itemName, itemID, cmItemStatus.getFancyValue());
postMessageToStream(getGCatZulipRestExecutor(), cmItemStatus, message);
}
public void postItemUpdated() throws Exception{
String username = ckanUser.getPortalUser().getNameSurname();
CMItemStatus cmItemStatus = CMItemStatus.PENDING;
String message = String.format("@**%s** has updated the item with name '%s' (id='%s'). The item is now in **%s** state and must be moderated.",
username, itemName, itemID, cmItemStatus.getFancyValue());
postMessageToStream(getGCatZulipRestExecutor(), cmItemStatus, message);
}
public void postItemRejected(String userMessage) throws Exception {
String username = ckanUser.getPortalUser().getNameSurname();
CMItemStatus cmItemStatus = CMItemStatus.REJECTED;
String message = String.format("@**%s** has **%s** the item with name '%s' (id='%s'). The author can delete the item or update it to try to meet moderators requests if any.",
username, cmItemStatus.getFancyValue(), itemName, itemID);
postMessageToStream(getGCatZulipRestExecutor(), cmItemStatus, message);
postUserMessageToStream(cmItemStatus, userMessage);
}
public void postItemApproved(String userMessage) throws Exception{
String username = ckanUser.getPortalUser().getNameSurname();
CMItemStatus cmItemStatus = CMItemStatus.APPROVED;
String message = String.format("@**%s** has **%s** the item with name '%s' (id='%s'). The item is now available in the catalogue.",
username, cmItemStatus.getFancyValue(), itemName, itemID);
postMessageToStream(getGCatZulipRestExecutor(), cmItemStatus, message);
postUserMessageToStream(cmItemStatus, userMessage);
}
}

View File

@ -29,7 +29,7 @@ import org.gcube.gcat.api.CMItemVisibility;
import org.gcube.gcat.api.GCatConstants;
import org.gcube.gcat.api.Role;
import org.gcube.gcat.api.interfaces.Moderated;
import org.gcube.gcat.moderation.thread.zulip.ZulipStream;
import org.gcube.gcat.moderation.thread.ModerationThread;
import org.gcube.gcat.oldutils.Validator;
import org.gcube.gcat.profile.MetadataUtility;
import org.gcube.gcat.social.PortalUser;
@ -44,6 +44,7 @@ import org.slf4j.LoggerFactory;
public class CKANPackage extends CKAN implements Moderated {
private static final Logger logger = LoggerFactory.getLogger(CKANPackage.class);
/*
// see https://docs.ckan.org/en/latest/api/#ckan.logic.action.get.package_list
public static final String ITEM_LIST = CKAN.CKAN_API_PATH + "package_list";
@ -122,7 +123,7 @@ public class CKANPackage extends CKAN implements Moderated {
protected final CKANInstance ckanInstance;
protected final Set<String> supportedOrganizations;
protected ZulipStream zulipStream;
protected ModerationThread moderationThread;
public CKANPackage() {
super();
@ -642,7 +643,7 @@ public class CKANPackage extends CKAN implements Moderated {
ArrayNode created = createResources(resourcesToBeCreated);
((ObjectNode) result).replace(RESOURCES_KEY, created);
createZulipStream();
postItemCreated();
if(!isModerationEnabled()) {
if(ckanInstance.getCurrentScopeBean().is(Type.VRE)) {
@ -718,7 +719,7 @@ public class CKANPackage extends CKAN implements Moderated {
ckanResource.deleteFile();
}
postItemUpdatedToStream();
postItemUpdated();
return getAsCleanedString(result);
} catch(WebApplicationException e) {
@ -787,7 +788,7 @@ public class CKANPackage extends CKAN implements Moderated {
ckanResource.deleteFile();
}
postItemUpdatedToStream();
postItemUpdated();
return getAsCleanedString(result);
} catch(WebApplicationException e) {
@ -906,9 +907,9 @@ public class CKANPackage extends CKAN implements Moderated {
protected boolean isModerationEnabled() {
boolean moderationEnabled = ckanInstance.isModerationEnabled();
if(moderationEnabled && zulipStream==null) {
zulipStream = new ZulipStream();
zulipStream.setCKANUser(ckanUser);
if(moderationEnabled && moderationThread==null) {
moderationThread = ModerationThread.getDefaultInstance();
moderationThread.setCKANUser(ckanUser);
}
return moderationEnabled;
}
@ -1146,11 +1147,11 @@ public class CKANPackage extends CKAN implements Moderated {
((ObjectNode) jsonNode).put(SEARCHABLE_KEY, true);
}
private void createZulipStream() throws Exception {
private void postItemCreated() throws Exception {
try {
if(isModerationEnabled()) {
zulipStream.setItemCoordinates(itemID, name);
zulipStream.create();
moderationThread.setItemCoordinates(itemID, name);
moderationThread.postItemCreated();
}
} catch(WebApplicationException e) {
throw e;
@ -1159,11 +1160,11 @@ public class CKANPackage extends CKAN implements Moderated {
}
}
private void postItemUpdatedToStream() {
private void postItemUpdated() {
try {
if(isModerationEnabled()) {
zulipStream.setItemCoordinates(itemID, name);
zulipStream.postItemUpdated();
moderationThread.setItemCoordinates(itemID, name);
moderationThread.postItemUpdated();
}
} catch(WebApplicationException e) {
throw e;
@ -1195,8 +1196,8 @@ public class CKANPackage extends CKAN implements Moderated {
String ret = sendPostRequest(ITEM_PATCH, getAsString(result));
result = mapper.readTree(ret);
zulipStream.setItemCoordinates(itemID, name);
zulipStream.postItemApproved(moderatorMessage);
moderationThread.setItemCoordinates(itemID, name);
moderationThread.postItemApproved(moderatorMessage);
if(ckanInstance.getCurrentScopeBean().is(Type.VRE)) {
// Actions performed after a package has been correctly created on ckan.
@ -1244,8 +1245,8 @@ public class CKANPackage extends CKAN implements Moderated {
String ret = sendPostRequest(ITEM_PATCH, getAsString(result));
result = mapper.readTree(ret);
zulipStream.setItemCoordinates(itemID, name);
zulipStream.postItemRejected(moderatorMessage);
moderationThread.setItemCoordinates(itemID, name);
moderationThread.postItemRejected(moderatorMessage);
break;
default:
@ -1283,8 +1284,8 @@ public class CKANPackage extends CKAN implements Moderated {
}
CMItemStatus cmItemStatus = getCMItemStatus();
zulipStream.setItemCoordinates(itemID, name);
zulipStream.postUserMessageToStream(cmItemStatus, message);
moderationThread.setItemCoordinates(itemID, name);
moderationThread.postUserMessage(cmItemStatus, message);
return;
}
throw new MethodNotSupportedException("The message operation is available only in moderation mode");