Category Tile View: Showing wrong Reply Count - sharepoint-2013

In SharePoint Community site , Category Tile view is showing wrong count of reply. In general Category total replies are 5 but in Category tile view it is showing 3. This behaviour we are able to replicate both in our test and Production environment. We also waited for one day , if this issue related to Crawl but issue still persists.
Please give some suggestions on this.
Thanks,
Sheetal

I had the exact same problem and there was no fix available. In my opinion these counters are updated through event receivers, so this has nothing to do with search crawls.
I solved this by setting the correct fields by code:
First count the topics and replies with this SSOM code
/// <summary>
/// Dictionary: categId, nr disc
/// </summary>
public Dictionary<int, int> CategoryTopicCount
{
get
{
var categoriesDiscussionsCount = new Dictionary<int, int>();
foreach (int categId in Categories)
{
var spquery = new SPQuery();
spquery.Query = ""
+ " <Where>"
+ " <And> "
+ " <IsNull>"
+ " <FieldRef Name='ParentFolderId' />"
+ " </IsNull>"
+ " <Eq>"
+ " <FieldRef Name='CategoriesLookup' LookupId='TRUE' />"
+ " <Value Type='Lookup'>" + categId + "</Value>"
+ " </Eq>"
+ " </And> "
+ " </Where>";
spquery.ViewAttributes = "Scope='RecursiveAll'";
categoriesDiscussionsCount.Add(categId, _discussionList.GetItems(spquery).Count);
}
return categoriesDiscussionsCount;
}
}
/// <summary>
/// Dictionary: categId, nr replies
/// </summary>
public Dictionary<int, int> CategoryReplyCount
{
get
{
var categoriesDiscussionsCount = new Dictionary<int, int>();
foreach (int categId in Categories)
{
//get topics of this category
var spquery = new SPQuery();
spquery.Query = ""
+ " <Where>"
+ " <And> "
+ " <IsNull>"
+ " <FieldRef Name='ParentFolderId' />"
+ " </IsNull>"
+ " <Eq>"
+ " <FieldRef Name='CategoriesLookup' LookupId='TRUE' />"
+ " <Value Type='Lookup'>" + categId + "</Value>"
+ " </Eq>"
+ " </And> "
+ " </Where>";
spquery.ViewAttributes = "Scope='RecursiveAll'";
SPListItemCollection topicsOfThisCategory = _discussionList.GetItems(spquery);
//get nr of replies for each topic of this category
var totalRepliesCategory = 0;
foreach (SPListItem topic in topicsOfThisCategory)
{
var spqueryreplies = new SPQuery();
spqueryreplies.Query = ""
+ " <Where>"
+ " <And> "
+ " <IsNotNull>"
+ " <FieldRef Name='ParentFolderId' />"
+ " </IsNotNull>"
+ " <Eq>"
+ " <FieldRef Name='ParentFolderId' />"
+ " <Value Type='Number'>" + topic.ID + "</Value>"
+ " </Eq>"
+ " </And> "
+ " </Where>";
spqueryreplies.ViewAttributes = "Scope='RecursiveAll'";
totalRepliesCategory += _discussionList.GetItems(spqueryreplies).Count;
}
categoriesDiscussionsCount.Add(categId, totalRepliesCategory);
}
return categoriesDiscussionsCount;
}
}
Then update the counters with this SSOM code:
/// <summary>
/// Update number of topics and replies for each category
/// </summary>
public void UpdateCategoriesCounts()
{
Dictionary<int, int> categoryTopicCount = this.CategoryTopicCount;
Dictionary<int, int> categoryReplyCount = this.CategoryReplyCount;
SPListItemCollection categories = _categoryList.Items;
foreach (SPListItem category in categories)
{
Console.WriteLine("Handling " + category.DisplayName);
int topicCount = category["TopicCount"] == null ? 0 : Convert.ToInt32(category["TopicCount"]);
int replyCount = category["ReplyCount"] == null ? 0 : Convert.ToInt32(category["ReplyCount"]);
Console.WriteLine("Topics: " + categoryTopicCount[category.ID] + " || Replies: " + categoryReplyCount[category.ID]);
_web.AllowUnsafeUpdates = true;
if (categoryTopicCount[category.ID] != topicCount)
category["TopicCount"] = categoryTopicCount[category.ID];
if (categoryReplyCount[category.ID] != replyCount)
category["ReplyCount"] = categoryReplyCount[category.ID];
category.SystemUpdate(false);
_web.AllowUnsafeUpdates = false;
Console.WriteLine("Saved...");
}
Console.WriteLine("Finished");
}
Hope this helps you!
PS: the same problem might occure with the 'my membership'-counters. Here we can also adjust the values through code. Check this: SharePoint 'my membership' webpart counters in community site

Related

How to properly make and sign http request to query AWS cloudwatch metrics using JSON payload

I'm trying to make my own HTTP request to query cloudwatch metrics from AWS API. The reason is because I need to define my query in JSON format (similar to how aws cloudwatch get-metric-data --cli-input-json <json_file_name> works). And according to this link, this should be possible. However, I'm having some trouble properly making and signing my HTTP request. With the following code, I'm getting {"__type":"com.amazon.coral.service#UnknownOperationException"} error. And there is little information in the response to help me troubleshoot. Am I signing my request wrong? Or am I missing some parameters/headers?
String query = "{\n" +
" \"StartTime\": 1628589600,\n" +
" \"EndTime\": 1628590200,\n" +
" \"MetricDataQueries\": [\n" +
" {\n" +
" \"Id\": \"mymetric1\",\n" +
" \"Label\": \"counter\",\n" +
" \"MetricStat\": {\n" +
" \"Metric\": {\n" +
" \"Namespace\": \"AWS/EC2\",\n" +
" \"MetricName\": \"CPUUtilization\",\n" +
" \"Dimensions\": [\n" +
" {\n" +
" \"Name\": \"InstanceId\",\n" +
" \"Value\": \"my_instance_id\"\n" +
" }\n" +
" ]\n" +
" },\n" +
" \"Period\": 60,\n" +
" \"Stat\": \"Average\",\n" +
" \"Unit\": \"Percent\"\n" +
" }\n" +
" }\n" +
" ]\n" +
"}";
ProfileCredentialsProvider credProvider = ProfileCredentialsProvider.builder()
.profileName("my_profile").build();
Aws4PresignerParams params = Aws4PresignerParams.builder()
.doubleUrlEncode(true)
.awsCredentials(credProvider.resolveCredentials())
.signingName("monitoring")
.signingRegion(Region.US_EAST_1)
.timeOffset(0)
.build();
SdkHttpFullRequest requestToSign = SdkHttpFullRequest.builder()
.method(SdkHttpMethod.POST)
.protocol("https")
.host("monitoring.us-east-1.amazonaws.com")
.appendRawQueryParameter("Action", "GetMetricData")
.appendRawQueryParameter("Version", "2010-08-01")
.appendRawQueryParameter("StartTime", "1628589600")
.appendRawQueryParameter("EndTime", "1628590200")
.appendRawQueryParameter("MetricDataQueries.member.N", "1")
.contentStreamProvider(() -> new ByteArrayInputStream(query.getBytes(StandardCharsets.UTF_8)))
.build();
SdkHttpFullRequest signedRequest = AwsS3V4Signer.create().presign(requestToSign, params);
URL url = signedRequest.getUri().toURL();
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = RequestBody.create(query.getBytes(StandardCharsets.UTF_8), MediaType.parse("application/x-amz-json-1.0"));
Request r = new Request.Builder()
.url(url)
.post(requestBody)
.build();
try (Response response = client.newCall(r).execute()) {
System.out.println(response.body().string());
}

Why do profile pic URLs returned from graph.facebook result in a 404

The backend of my application makes a request to:
https://graph.facebook.com/v2.8/me?access_token=<firebase-access-token>&fields=id,name,first_name,birthday,email,picture.type(large){url}&format=json&method=get&pretty=0&suppress_http_code=1
I get a successful (200) response with the JSON data I expect and picture field as such:
"picture": {
"data": {
"url": "https://platform-lookaside.fbsbx.com/platform/profilepic/?asid=<asid>&height=200&width=200&ext=<ext>&hash=<hash>"
}
}
(where in place of <asid> and <ext>, there are numbers and <hash> is some alphanumeric string).
However, when I make a GET request to the platform-lookaside URL above, I get a 404 error.
It's been happening every time since my very first graph.facebook request for the same user. The very first one returned a platform-lookaside URL which pointed to a proper image (not sure if this is simply coincidence).
Is there something I'm doing wrong or is this likely a bug with the Facebook API?
FB currently seems to have issues with some CDNs and therefore your issue might be only temporary. You should also see missing/broken images on some places on fb dot com. Worst time to debug your issue :)
Try this code it worked for me
GraphRequest request = GraphRequest.newMeRequest(
AccessToken.getCurrentAccessToken(), new GraphRequest.GraphJSONObjectCallback() {
#Override
public void onCompleted(JSONObject object, GraphResponse response) {
// Insert your code here
try {
String name = object.getString("name");
String email = object.getString("email");
String last_name = object.getString("last_name");
String first_name = object.getString("first_name");
String middle_name = object.getString("middle_name");
String link = object.getString("link");
String picture = object.getJSONObject("picture").getJSONObject("data").getString("url");
Log.e("Email = ", " " + email);
Log.e("facebookLink = ", " " + link);
Log.e("name = ", " " + name);
Log.e("last_name = ", " " + last_name);
Log.e("first_name = ", " " + first_name);
Log.e("middle_name = ", " " + middle_name);
Log.e("pictureLink = ", " " + picture);
} catch (JSONException e) {
e.printStackTrace();
Log.e("Sttaaaaaaaaaaaaaaaaa", e.getMessage());
}
}
});
Bundle parameters = new Bundle();
parameters.putString("fields", "id,name,email,link,last_name,first_name,middle_name,picture");
request.setParameters(parameters);
request.executeAsync();

How to start the stream processor in Amazon Rekognition

I followed the AWS Rekognition Developer Guide and wrote a stream processor using CreateStreamProcessor in Java.
import com.amazonaws.services.rekognition.AmazonRekognition;
import com.amazonaws.services.rekognition.AmazonRekognitionClientBuilder;
import com.amazonaws.services.rekognition.model.*;
public class StreamProcessor {
private String streamProcessorName;
private String kinesisVideoStreamArn;
private String kinesisDataStreamArn;
private String roleArn;
private String collectionId;
private float matchThreshold;
private AmazonRekognition rekognitionClient = AmazonRekognitionClientBuilder.defaultClient();
public void createStreamProcessor() {
KinesisVideoStream kinesisVideoStream = new KinesisVideoStream().withArn(kinesisVideoStreamArn);
StreamProcessorInput streamProcessorInput = new StreamProcessorInput().withKinesisVideoStream(kinesisVideoStream);
KinesisDataStream kinesisDataStream = new KinesisDataStream().withArn(kinesisDataStreamArn);
StreamProcessorOutput streamProcessorOutput = new StreamProcessorOutput().withKinesisDataStream(kinesisDataStream);
FaceSearchSettings faceSearchSettings = new FaceSearchSettings().withCollectionId(collectionId)
.withFaceMatchThreshold(matchThreshold);
StreamProcessorSettings streamProcessorSettings = new StreamProcessorSettings().withFaceSearch(faceSearchSettings);
CreateStreamProcessorResult createStreamProcessorResult = rekognitionClient.createStreamProcessor(
new CreateStreamProcessorRequest().withInput(streamProcessorInput).withOutput(streamProcessorOutput)
.withSettings(streamProcessorSettings).withRoleArn(roleArn).withName(streamProcessorName));
System.out.println("StreamProcessorArn - " +
createStreamProcessorResult.getStreamProcessorArn());
}
public void startStreamProcessor() {
StartStreamProcessorResult startStreamProcessorResult = rekognitionClient.startStreamProcessor(
new StartStreamProcessorRequest().withName(streamProcessorName));
}
public void stopStreamProcessorSample() {
StopStreamProcessorResult stopStreamProcessorResult = rekognitionClient.stopStreamProcessor(
new StopStreamProcessorRequest().withName(streamProcessorName));
}
public void deleteStreamProcessorSample() {
DeleteStreamProcessorResult deleteStreamProcessorResult = rekognitionClient.deleteStreamProcessor(
new DeleteStreamProcessorRequest().withName(streamProcessorName));
}
public void describeStreamProcessorSample() {
DescribeStreamProcessorResult describeStreamProcessorResult = rekognitionClient.describeStreamProcessor(
new DescribeStreamProcessorRequest().withName(streamProcessorName));
System.out.println("Arn - " + describeStreamProcessorResult.getStreamProcessorArn());
System.out.println("Input kinesisVideo stream - " + describeStreamProcessorResult.getInput()
.getKinesisVideoStream().getArn());
System.out.println("Output kinesisData stream - " + describeStreamProcessorResult.getOutput()
.getKinesisDataStream().getArn());
System.out.println("RoleArn - " + describeStreamProcessorResult.getRoleArn());
System.out.println("CollectionId - " + describeStreamProcessorResult.getSettings().getFaceSearch()
.getCollectionId());
System.out.println("Status - " + describeStreamProcessorResult.getStatus());
System.out.println("Status message - " + describeStreamProcessorResult.getStatusMessage());
System.out.println("Creation timestamp - " + describeStreamProcessorResult.getCreationTimestamp());
System.out.println("Last updatClient rekognitionClient = new AmazonRekognitionClient()e timestamp - "
+ describeStreamProcessorResult.getLastUpdateTimestamp());
}
public void listStreamProcessorSample() {
ListStreamProcessorsResult listStreamProcessorsResult = rekognitionClient.listStreamProcessors(
new ListStreamProcessorsRequest().withMaxResults(100));
for (com.amazonaws.services.rekognition.model.StreamProcessor streamProcessor :
listStreamProcessorsResult.getStreamProcessors()) {
System.out.println("StreamProcessor name - " + streamProcessor.getName());
System.out.println("Status - " + streamProcessor.getStatus());
}
}
}
But I can't figure out how to start the stream processor? Do I have to simply write the main method and call createStreamProcessor() function? Or do I have to do something else: like the guide mentioned something as StartStreamProcessor?
Yes, you have to start the stream preprocessor by using following API:
https://docs.aws.amazon.com/rekognition/latest/dg/API_StartStreamProcessor.html
rekognitionClient.startStreamProcessor(name= "my-stream-1")

DynamoDb putItem ConditionExpression in c++ - add or update

My putItem is working. Now I want to make sure I update only newer information to an existing item, or add this as a new item:
ConditionlExpression:
Create new item if partition:sort doesn't exist
Update if attribute generated < :newTimestamp
So I added one line to code:
putItemRequest.SetConditionExpression(" attribute_not_exists(" + partitionName + ") OR (attribute_exists(" + partitionName + ") AND (" + timestampName + " < :" + timestamp + "))");
This should create a new item, but it looks to be trying to evaluate the attribute 'generated' when it does not exist for a new item.
The error on putItem return:
Invalid ConditionExpression: An expression attribute value used in expression is not defined; attribute value: :1461782160
From the debugger the conditionExpression look like:
m_conditionExpression = " attribute_not_exists(airport) OR (attribute_exists(airport) AND (generated < :1461782160))"
I am trying to avoid:
looking up the partition:sort
if it does not exist, putItem
else check the generated attribute
then if generated < newTimestamp update the item
Is there a way to construct the conditionExpression to meet my expectation?
Edit: Same problem when using updateItem
Code:
UpdateItemRequest updateItemRequest;
updateItemRequest.WithTableName(dynamoDbTableName);
AttributeValue hashPartition;
hashPartition.SetS(partition);
updateItemRequest.AddKey(partitionName, hashPartition);
AttributeValue hashSort;
hashSort.SetS(sort);
updateItemRequest.AddKey(sortName, hashSort);
AttributeValue hashAttribute;
hashAttribute.SetS(attribute);
Aws::Map<Aws::String, AttributeValue> attributeMap;
attributeMap[":a"] = hashAttribute;
updateItemRequest.SetUpdateExpression("SET " + timestampName + " = :" + timestamp + ", " + attributeName + " = :a");
updateItemRequest.SetExpressionAttributeValues(attributeMap);
// Allow only older items to be updated
updateItemRequest.SetConditionExpression("(" + timestampName + " < :" + timestamp + ")");
auto updateItemOutcome = dynamoDbClient.UpdateItem(updateItemRequest);
Error:
Invalid UpdateExpression: An expression attribute value used in expression is not defined; attribute value: :1461781980
That attribute value is the timestamp. It's not defined because this item doesn't exist and should be created.
Here is my current work around:
ClientConfiguration config;
config.region = Aws::Region::US_WEST_2;
Aws::DynamoDB::DynamoDBClient dynamoDbClient(config);
Aws::Map<Aws::String, AttributeValue> aMap;
PutItemRequest putItemRequest;
putItemRequest.WithTableName(dynamoDbTableName);
AttributeValue hashPartition;
hashPartition.SetS(partition);
putItemRequest.AddItem(partitionName, hashPartition);
aMap[":p"] = hashPartition;
AttributeValue hashSort;
hashSort.SetS(sort);
putItemRequest.AddItem(sortName, hashSort);
aMap[":s"] = hashSort;
AttributeValue hashTimestamp;
hashTimestamp.SetN(timestamp);
putItemRequest.AddItem(timestampName, hashTimestamp);
AttributeValue hashAttribute;
hashAttribute.SetS(attribute);
putItemRequest.AddItem(attributeName, hashAttribute);
// Do not update existing items
putItemRequest.SetConditionExpression("NOT((" + partitionName + " = :p) AND (" + sortName + " = :s))");
putItemRequest.SetExpressionAttributeValues(aMap);
auto putItemOutcome = dynamoDbClient.PutItem(putItemRequest);
if(putItemOutcome.IsSuccess())
{
poco_information(logger, "writeDb PutItem Success: " + partition + ":" + sort);
status = SWIMPROCESSOR_OK;
}
else
{
if(putItemOutcome.GetError().GetErrorType() == DynamoDBErrors::CONDITIONAL_CHECK_FAILED) {
// item exists, try to update
Aws::Map<Aws::String, AttributeValue> uMap;
uMap[":t"] = hashTimestamp;
uMap[":a"] = hashAttribute;
UpdateItemRequest updateItemRequest;
updateItemRequest.WithTableName(dynamoDbTableName);
updateItemRequest.AddKey(partitionName, hashPartition);
updateItemRequest.AddKey(sortName, hashSort);
updateItemRequest.SetUpdateExpression("SET " + timestampName + " = :t, " + attributeName + " = :a");
updateItemRequest.SetExpressionAttributeValues(uMap);
// Allow only older items to be updated
updateItemRequest.SetConditionExpression(timestampName + " < :t");
auto updateItemOutcome = dynamoDbClient.UpdateItem(updateItemRequest);
if(updateItemOutcome.IsSuccess())
{
poco_information(logger, "writeDb UpdateItem Success: " + partition + ":" + sort);
status = SWIMPROCESSOR_OK;
}
else
{
if(putItemOutcome.GetError().GetErrorType() == DynamoDBErrors::CONDITIONAL_CHECK_FAILED) {
poco_information(logger, "writeDB UpdateItem new timestamp is older then current timestamp");
status = SWIMPROCESSOR_OK;
} else {
std::string msg(updateItemOutcome.GetError().GetMessage());
poco_error(logger, "writeDb UpdateItem Failure: " + msg);
status = SWIMPROCESSOR_DBWRITEERROR;
}
}
} else {
std::string msg(putItemOutcome.GetError().GetMessage());
poco_error(logger, "writeDb PutItem Failure: " + msg);
status = SWIMPROCESSOR_DBWRITEERROR;
}
}
The service's error message says that you need to put :1461782160 in the attributeMap. UpdateExpression should be "SET " + timestampName + " = :timestamp, " + attributeName + " = :a"
and your map should be defined as follows.
AttributeValue hashAttributeA;
hashAttributeA.SetS(attribute)
AttributeValue hashAttributeTimestamp;
hashAttributeTimestamp.SetN(timestamp)
Aws::Map<Aws::String, AttributeValue> attributeMap;
attributeMap[":a"] = hashAttributeA;
attributeMap[":timestamp"] = hashAttributeTimestamp;

UploadFile doesn´t work

Hi we are using "dropnet" API and works fine until today, just is not working the UploadFile method, play media, move or delete works fine, but the upload is not working can someone help to figuredout why?
basically the process upload the file and returns no error, but the file (.mp3 files) is not uploaded into my dropbox account as had been doing until last Friday. We tried to move or delete a file, also play the mp3 from my web page and it works perfect! How can we try to catch the error?
we use this code:
var fecha = DateTime.Now.ToString("dd-MM-yyyy");
DropNet.Models.MetaData uploaded = new DropNet.Models.MetaData();
uploaded = _client.UploadFile("/CRM_Proximitas/" + portal + "/" + Request.QueryString["idReclamo"].ToString() + "/" + fecha, hidTipo.Value.ToString() + hidID.Value.ToString() + "_" + fecha + "_" + usuario + "." + uplArchivo.FileName.ToLower().Split('.')[1], uplArchivo.FileBytes);
if (uploaded != null)
{
if (hidTipo.Value.ToString() == "R")
{
objCommand.CommandText = "INSERT INTO ReclamoAudio (idReclamo,path,Autor,Fecha) VALUES (" + Request.QueryString["idReclamo"].ToString() + ",'" + uploaded.Path.ToString() + "'," + Session["UserID"].ToString() + ",getdate())";
}
else if (hidTipo.Value.ToString() == "T")
{
objCommand.CommandText = "INSERT INTO ReclamoAudio (idReclamo,idTransaccion,path,Autor,Fecha) VALUES (" + Request.QueryString["idReclamo"].ToString() + "," + hidID.Value.ToString() + ",'" + uploaded.Path.ToString() + "'," + Session["UserID"].ToString() + ",getdate())";
}
objCommand.CommandType = CommandType.Text;
objCon.Open();
drContacto = objCommand.ExecuteReader();
objCon.Close();
string codigo = "window.opener.location.reload();self.close();";
Page.ClientScript.RegisterStartupScript(this.GetType(), "FinalizarCarga", codigo, true);
}
We have a website with IIS 7 + Framework 2.0, also the Dropbox App now is in Development Status, this can we cause an issue?
Please I need your help.
Thanks a lot!