in code/Server/Common/Managers/CVSModerationManager.cs [297:484]
public async Task SubmitContentForModeration(
ProcessType processType,
string appHandle,
string moderationHandle,
ContentType contentType,
string contentHandle,
Uri callbackUri)
{
// if init has not yet been called, do it now.
if (this.initStarted == false)
{
await this.Init();
}
// if init is not yet done, wait for it to finish.
this.initDone.WaitOne();
// check input
if (string.IsNullOrWhiteSpace(appHandle))
{
throw new ArgumentNullException("appHandle");
}
if (string.IsNullOrWhiteSpace(moderationHandle))
{
throw new ArgumentNullException("moderationHandle");
}
if (string.IsNullOrWhiteSpace(contentHandle))
{
throw new ArgumentNullException("contentHandle");
}
if (callbackUri == null)
{
throw new ArgumentNullException("callbackUri");
}
// extract the content to be submitted for moderation
string userHandle = string.Empty;
string text1 = string.Empty;
string text2 = string.Empty;
string imageHandle = null;
switch (contentType)
{
case ContentType.Topic:
ITopicEntity topicEntity = await this.topicsManager.ReadTopic(contentHandle);
if (topicEntity == null)
{
// nothing more to do here; it has already been deleted
this.log.LogInformation("Topic has already been deleted for appHandle " + appHandle + " and moderationHandle " + moderationHandle);
return;
}
else if (topicEntity.ReviewStatus == ReviewStatus.Banned)
{
// nothing more to do here; it has already been banned
this.log.LogInformation("Topic has already been banned for appHandle " + appHandle + " and moderationHandle " + moderationHandle);
return;
}
text1 = topicEntity.Title;
text2 = topicEntity.Text;
if (topicEntity.BlobType == BlobType.Image && !string.IsNullOrWhiteSpace(topicEntity.BlobHandle))
{
imageHandle = topicEntity.BlobHandle;
}
userHandle = topicEntity.UserHandle;
break;
case ContentType.Comment:
ICommentEntity commentEntity = await this.commentsManager.ReadComment(contentHandle);
if (commentEntity == null)
{
// nothing more to do here; it has already been deleted
this.log.LogInformation("Comment has already been deleted for appHandle " + appHandle + " and moderationHandle " + moderationHandle);
return;
}
else if (commentEntity.ReviewStatus == ReviewStatus.Banned)
{
// nothing more to do here; it has already been banned
this.log.LogInformation("Comment has already been banned for appHandle " + appHandle + " and moderationHandle " + moderationHandle);
return;
}
text1 = commentEntity.Text;
if (commentEntity.BlobType == BlobType.Image && !string.IsNullOrWhiteSpace(commentEntity.BlobHandle))
{
imageHandle = commentEntity.BlobHandle;
}
userHandle = commentEntity.UserHandle;
break;
case ContentType.Reply:
IReplyEntity replyEntity = await this.repliesManager.ReadReply(contentHandle);
if (replyEntity == null)
{
// nothing more to do here; it has already been deleted
this.log.LogInformation("Reply has already been deleted for appHandle " + appHandle + " and moderationHandle " + moderationHandle);
return;
}
else if (replyEntity.ReviewStatus == ReviewStatus.Banned)
{
// nothing more to do here; it has already been banned
this.log.LogInformation("Reply has already been banned for appHandle " + appHandle + " and moderationHandle " + moderationHandle);
return;
}
text1 = replyEntity.Text;
userHandle = replyEntity.UserHandle;
break;
default:
// this should never happen; throw an exception
this.log.LogException("Got an unexpected content type: " + contentType + " for appHandle " + appHandle + " and moderationHandle " + moderationHandle);
break;
}
// skip if there's nothing to be submitted for review
if (string.IsNullOrWhiteSpace(text1) && string.IsNullOrWhiteSpace(text2) && imageHandle == null)
{
// nothing we can do here since there is no content
this.log.LogInformation("The content is empty for appHandle " + appHandle + " and moderationHandle " + moderationHandle);
return;
}
CVSRequest cvsRequest = new CVSRequest(new Uri(this.cvsUrl), this.cvsKey);
CVSContent cvsContent = new CVSContent();
if (!string.IsNullOrWhiteSpace(text1))
{
cvsContent.AddText(text1);
}
if (!string.IsNullOrWhiteSpace(text2))
{
cvsContent.AddText(text2);
}
if (imageHandle != null)
{
// check to see that the image exists in our blob storage
if (await this.blobsManager.ImageExists(imageHandle))
{
// enforce that the version of the image we submit to cvs meets
// certain format requirements
var newImageHandle = await this.EnforceCVSImageFormat(imageHandle);
Uri imageUri = await this.blobsManager.ReadImageCdnUrl(newImageHandle);
if (imageUri != null)
{
cvsContent.AddImageUri(imageUri);
}
}
}
// create asynchronous job
var jobId = await cvsRequest.SubmitAsyncJob(cvsContent, callbackUri);
var submissionTime = DateTime.UtcNow;
// store cvs transaction
await this.cvsTransactionStore.InsertTransaction(
StorageConsistencyMode.Strong,
moderationHandle,
appHandle,
ReportType.Content,
submissionTime,
cvsContent.GetContentItemsAsJson(),
jobId,
callbackUri.ToString());
// add moderation to content moderation store.
// this is necessary as it records the content lookup information, which
// would be required when CVS posts results back with a moderation handle
await this.moderationStore.InsertModeration(
StorageConsistencyMode.Strong,
moderationHandle,
imageHandle,
contentType,
contentHandle,
userHandle,
appHandle,
ImageType.ContentBlob,
ModerationStatus.Pending,
submissionTime);
}