I am trying to configure an existing AWS Dashboard with adding one new widget.
In Amazon Kinesis / Analytics application / Streaming application I click on the graphs 'View in metrics" of which I would like to add to my dashboard
In the next screen I click Actions / Add to dashboard
after selecting my dashboard I click add, and then I can see my dashboard with the chart:
However, if I click on "Save" I get the following error:
There was an error while trying to save your dashboard:
The dashboard body is invalid, there are 6 validation errors: [
{ "dataPath": "/widgets/5/properties/metrics/0", "message": "Should NOT have more than 4 items" },
{ "dataPath": "/widgets/5/properties/metrics/1", "message": "Should NOT have more than 4 items" },
{ "dataPath": "/widgets/5/properties/yAxis/left", "message": "Should be null" },
{ "dataPath": "/widgets/5/properties/yAxis/left", "message": "Should match some schema in anyOf" },
{ "dataPath": "/widgets/5/properties/yAxis/right", "message": "Should be null" },
{ "dataPath": "/widgets/5/properties/yAxis/right", "message": "Should match some schema in anyOf" } ]
I am totally clueless, as I did not enter anything manually, all I done was just clicking on the menu items. What is the problem here? I don't even understand the error messages even. I have 4 logs, and 1 chart already on the screen, this would be the 6th item if that is important.
Update: adding the source code of the template (I censored some sensitive information with "......."):
{
"widgets": [
{
"height": 6,
"width": 24,
"y": 12,
"x": 0,
"type": "log",
"properties": {
"query": "SOURCE '/aws/kinesis-analytics/.......' | fields #timestamp, message | filter applicationARN like /arn:aws:kinesisanalytics:eu-west-1:......./| filter messageType = \"ERROR\"| sort #timestamp desc",
"region": "eu-west-1",
"title": "Error log (last 1000 records)",
"view": "table"
}
},
{
"height": 6,
"width": 24,
"y": 6,
"x": 0,
"type": "log",
"properties": {
"query": "SOURCE '/aws/kinesis-analytics/.......' | fields #timestamp, message | filter applicationARN like /arn:aws:kinesisanalytics:eu-west-1:......./| sort #timestamp desc",
"region": "eu-west-1",
"title": "Full log (last 1000 records)",
"view": "table"
}
},
{
"height": 6,
"width": 24,
"y": 18,
"x": 0,
"type": "log",
"properties": {
"query": "SOURCE '/aws/kinesis-analytics/.......' | fields #timestamp, message | filter applicationARN like /arn:aws:kinesisanalytics:eu-west-1:......./| filter message like / OEE Data Streaming app v / | sort #timestamp desc",
"region": "eu-west-1",
"title": "Version - works only right after deployment, othervise look at the name of the jar file :) ",
"view": "table"
}
},
{
"height": 6,
"width": 24,
"y": 0,
"x": 0,
"type": "log",
"properties": {
"query": "SOURCE '/aws/kinesis-analytics/.......' | fields #timestamp, message | filter applicationARN like /arn:aws:kinesisanalytics:eu-west-1:338785721659:.......") | sort #timestamp desc",
"region": "eu-west-1",
"stacked": false,
"title": "OEE app inside logs",
"view": "table"
}
},
{
"height": 6,
"width": 6,
"y": 24,
"x": 0,
"type": "metric",
"properties": {
"region": "eu-west-1",
"yAxis": {
"left": {
"min": 0
}
},
"metrics": [
[ "AWS/Kinesis", "GetRecords.Records", "StreamName", ".......", { "id": "m3", "visible": true } ]
],
"stat": "Sum",
"title": "GetRecords - .......",
"start": "-PT3H",
"end": "P0D",
"view": "timeSeries",
"stacked": false
}
}
]
}
and if I try to add the uptime widget, it's code is this :
{
"type": "metric",
"x": 6,
"y": 24,
"width": 6,
"height": 6,
"properties": {
"region": "eu-west-1",
"yAxis": {
"left": {
"min": 0,
"stat": "Maximum",
"showUnits": false
},
"right": {
"min": 0,
"stat": "Maximum",
"showUnits": false
}
},
"metrics": [
[ "AWS/KinesisAnalytics", "uptime", "Application", "...", { "yAxis": "left", "label": "uptime", "stat": "Maximum", "showUnits": false } ],
[ ".", "fullRestarts", ".", ".", { "yAxis": "right", "label": "fullRestarts", "stat": "Maximum", "showUnits": false } ]
],
"stat": "Maximum",
"title": "Uptime (Milliseconds) - Maximum",
"start": "-PT3H",
"end": "P0D",
"view": "timeSeries",
"stacked": false
}
}
but I cannot save it now with the error message I described earlier.
Looks like the properties on axis definition and metric definition are mixed up.
Axis should not have the stat property: https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/CloudWatch-Dashboard-Body-Structure.html#CloudWatch-Dashboard-Properties-YAxis-Properties-Format
Metric definition should not have the showUnits property: https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/CloudWatch-Dashboard-Body-Structure.html#CloudWatch-Dashboard-Properties-Rendering-Object-Format
Try removing the stat property from both left and right axis definition. Also remove the showUnits property from the metrics definition (that should only be on the axis definitions).
If this was generated automatically, then it looks like a bug in the console.
I have two images with 40+ faces of people in it. I want to detect which faces are repeated in both images using AWS Rekognition service.
The original approach was to use the IndexFaces function of Rekognition and store all the faces of one image in one collection and the faces of the other image in another collection and then compare them using their FaceId. I thought that IndexFaces would provide a fingerprint for each face but it happens to be the FaceId is just a random identifier and not a fingerprint of the face.
I found this answer How to compare faces in a Collection to faces in a Stored Video using AWS Rekognition? but that compares all the faces in a collection with faces appearing in a video, so I would be forced to convert one of the images to a 1 second video containing the image as only frame.. which I think defeats the purpose of easy usage.
It has to be a way to compare two rekognition collections in order to check for repeated images that Im failing to find.
There are two ways you could go about this:
Option 1: Use ExternalImageID
This is similar to your method.
The important part is that when a face is added to a collection, you can provide an ExternalImageID. Later, when this face is matched with an image, Amazon Rekognition will return the ExternalImageID for the face.
For example, you could store a person's name or unique identifier in the ExternalImageID.
So, your process could look like this:
Call DetectFaces() on image 1
It will return a list of FaceDetails with a bounding box for each face
Loop through each returned face and use the provided bounding box to call IndexFaces() for each individual face, providing an ExternalImageID each time (it could just be an incrementing number)
Then, call IndexFaces() on image 2
If it finds any faces in the collection generated from image 1, it will provide the ExternalImageID of the matching face
Option 2: Use CompareFaces()
Compares a face in the source input image with each of the 100 largest faces detected in the target input image.
This takes one input face (the largest in the source image) and compares it to all faces in the target image. Therefore, you would follow a similar process to above:
Call DetectFaces() on image 1
It will return a list of FaceDetails with a bounding box for each face
Loop through each returned face and use the provided bounding box to call CompareFaces() for each individual face, comparing it to image 2
You will be provided with a confidence level of each potentially matching face
See: Comparing Faces in Images - Amazon Rekognition
So, the second method is easier if you are just comparing two images. The first method is better if you have already stored individual faces that you wish to use again in future calls.
Thanks to #John Rotenstein I was able to make a quick prototype using the was console:
Assuming that we have all the permissions and AWS console installed on the system and a S3 bucket called 'TestBucket' where all the images are stored, I did the following:
1.- Created a "Main Collection"
> aws rekognition create-collection --collection-id "MainCollection"
2.- Added one of the people I want to detect, I extracted the face from an individual face and ran IndexFace
> aws rekognition index-faces --image '{"S3Object":{"Bucket":"TestBucket","Name":"cristian.jpg"}}' --collection-id "MainCollection" --max-faces 100 --quality-filter "AUTO" --detection-attributes "ALL" --external-image-id "cristian.jpg"
The resulting FaceID is 'a54ef57e-7003-4721-b7e1-703d9f039da9'
3.- I added the second image to the collection:
> aws rekognition index-faces --image '{"S3Object":{"Bucket":"TestBucket","Name":"ImageContaining40plusfaces.jpg"}}' --collection-id "MainCollection" --max-faces 100 --quality-filter "AUTO" --detection-attributes "ALL" --external-image-id "ImageContaining40plusfaces.jpg"
resulted in 40+ entries like this one, showing only one for brevity:
{
"FaceRecords": [
{
"FaceDetail": {
"Confidence": 99.99859619140625,
"Eyeglasses": {
"Confidence": 54.99907684326172,
"Value": false
},
"Sunglasses": {
"Confidence": 54.99971389770508,
"Value": false
},
"Gender": {
"Confidence": 54.747318267822266,
"Value": "Male"
},
"Landmarks": [
{
"Y": 0.311367392539978,
"X": 0.1916557103395462,
"Type": "eyeLeft"
},
{
"Y": 0.3120582699775696,
"X": 0.20143891870975494,
"Type": "eyeRight"
},
{
"Y": 0.3355730175971985,
"X": 0.19253292679786682,
"Type": "mouthLeft"
},
{
"Y": 0.3361922800540924,
"X": 0.2005564421415329,
"Type": "mouthRight"
},
{
"Y": 0.32276451587677,
"X": 0.19691102206707,
"Type": "nose"
},
{
"Y": 0.30642834305763245,
"X": 0.1876278519630432,
"Type": "leftEyeBrowLeft"
},
{
"Y": 0.3037400245666504,
"X": 0.19379760324954987,
"Type": "leftEyeBrowRight"
},
{
"Y": 0.3029193580150604,
"X": 0.19078010320663452,
"Type": "leftEyeBrowUp"
},
{
"Y": 0.3041592836380005,
"X": 0.1995924860239029,
"Type": "rightEyeBrowLeft"
},
{
"Y": 0.3074571192264557,
"X": 0.20519918203353882,
"Type": "rightEyeBrowRight"
},
{
"Y": 0.30346789956092834,
"X": 0.2024637758731842,
"Type": "rightEyeBrowUp"
},
{
"Y": 0.3115418553352356,
"X": 0.1898096352815628,
"Type": "leftEyeLeft"
},
{
"Y": 0.3118479251861572,
"X": 0.1935078650712967,
"Type": "leftEyeRight"
},
{
"Y": 0.31028062105178833,
"X": 0.19159308075904846,
"Type": "leftEyeUp"
},
{
"Y": 0.31250447034835815,
"X": 0.19164365530014038,
"Type": "leftEyeDown"
},
{
"Y": 0.31221893429756165,
"X": 0.19937492907047272,
"Type": "rightEyeLeft"
},
{
"Y": 0.3123391270637512,
"X": 0.20295380055904388,
"Type": "rightEyeRight"
},
{
"Y": 0.31087613105773926,
"X": 0.2013435810804367,
"Type": "rightEyeUp"
},
{
"Y": 0.31308478116989136,
"X": 0.20125225186347961,
"Type": "rightEyeDown"
},
{
"Y": 0.3264555335044861,
"X": 0.19483911991119385,
"Type": "noseLeft"
},
{
"Y": 0.3265785574913025,
"X": 0.19839303195476532,
"Type": "noseRight"
},
{
"Y": 0.3319154679775238,
"X": 0.196599081158638,
"Type": "mouthUp"
},
{
"Y": 0.3392537832260132,
"X": 0.19649912416934967,
"Type": "mouthDown"
},
{
"Y": 0.311367392539978,
"X": 0.1916557103395462,
"Type": "leftPupil"
},
{
"Y": 0.3120582699775696,
"X": 0.20143891870975494,
"Type": "rightPupil"
},
{
"Y": 0.31476160883903503,
"X": 0.18458032608032227,
"Type": "upperJawlineLeft"
},
{
"Y": 0.3398161828517914,
"X": 0.18679481744766235,
"Type": "midJawlineLeft"
},
{
"Y": 0.35216856002807617,
"X": 0.19623762369155884,
"Type": "chinBottom"
},
{
"Y": 0.34082692861557007,
"X": 0.2045571506023407,
"Type": "midJawlineRight"
},
{
"Y": 0.3160339295864105,
"X": 0.20668834447860718,
"Type": "upperJawlineRight"
}
],
"Pose": {
"Yaw": 4.778820514678955,
"Roll": 1.7387386560440063,
"Pitch": 11.82911205291748
},
"Emotions": [
{
"Confidence": 47.9405403137207,
"Type": "CALM"
},
{
"Confidence": 45.432857513427734,
"Type": "ANGRY"
},
{
"Confidence": 45.953487396240234,
"Type": "HAPPY"
},
{
"Confidence": 45.215728759765625,
"Type": "SURPRISED"
},
{
"Confidence": 50.013206481933594,
"Type": "SAD"
},
{
"Confidence": 45.30225372314453,
"Type": "CONFUSED"
},
{
"Confidence": 45.14192199707031,
"Type": "DISGUSTED"
}
],
"AgeRange": {
"High": 43,
"Low": 26
},
"EyesOpen": {
"Confidence": 54.95812225341797,
"Value": true
},
"BoundingBox": {
"Width": 0.02271346002817154,
"Top": 0.28692546486854553,
"Left": 0.1841897815465927,
"Height": 0.06893482059240341
},
"Smile": {
"Confidence": 53.493797302246094,
"Value": false
},
"MouthOpen": {
"Confidence": 53.51670837402344,
"Value": false
},
"Quality": {
"Sharpness": 53.330047607421875,
"Brightness": 81.31917572021484
},
"Mustache": {
"Confidence": 54.971839904785156,
"Value": false
},
"Beard": {
"Confidence": 54.136474609375,
"Value": false
}
},
"Face": {
"BoundingBox": {
"Width": 0.02271346002817154,
"Top": 0.28692546486854553,
"Left": 0.1841897815465927,
"Height": 0.06893482059240341
},
"FaceId": "570eb8a6-72b8-4381-a1a2-9112aa2b348e",
"ExternalImageId": "ImageContaining40plusfaces.jpg",
"Confidence": 99.99859619140625,
"ImageId": "7f09400e-2de8-3d11-af05-223f13f9ef76"
}
}
]
}
3.- Then I issued a SearchFacesById using the FaceId detected previously:
> aws rekognition search-faces --face-id "a54ef57e-7003-4721-b7e1-703d9f039da9" --collection-id "MainCollection"
and Voila! I got the face detected on the second source image as needed...
{
"SearchedFaceId": "a54ef57e-7003-4721-b7e1-703d9f039da9",
"FaceModelVersion": "4.0",
"FaceMatches": [
{
"Face": {
"BoundingBox": {
"Width": 0.022825799882411957,
"Top": 0.31017398834228516,
"Left": 0.4018920063972473,
"Height": 0.06067270040512085
},
"FaceId": "bfd58e70-2bcf-403a-87da-6137c28ccbdd",
"ExternalImageId": "ImageContaining40plusfaces.jpg",
"Confidence": 100.0,
"ImageId": "7f09400e-2de8-3d11-af05-223f13f9ef76"
},
"Similarity": 92.36637115478516
}
]
}
So now I have to do the same thing for all the other face images detected in the source image nº1 and then compare them to the ones detected from the source image nº2 using the same set of commands!
I'm attempting to use Boost to read a JSON file from my Firefox configuration folder called sessionstore.js, where the information on the current/last Firefox session is saved for purposes of recovery. I've written a program based on the XML-based tutorial from the Boost website, simply swapping out the XML parts for the JSON parts, which can be seen below
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>
#include <string>
#include <set>
#include <exception>
using boost::property_tree::ptree;
using namespace std;
const string FILENAME = "sessionstore.js";
const string WINDOW_TAG = "windows";
struct session_settings
{
void load (const string &FILENAME);
};
void session_settings::load (const string &FILENAME)
{
ptree pt;
read_json (FILENAME, pt);
}
int main()
{
try
{
session_settings Settings;
Settings.load(FILENAME);
}
catch (exception &e)
{
cout << "Error: " << e.what() << endl;
}
return 0;
}
The contents of the JSON file I'm trying to read are
{"windows":[{"tabs":[{"entries":[{"url":"about:home","title":"Mozilla Firefox Start Page","ID":5,"docshellID":11,"owner_b64":"NhAra3tiRRqhyKDUVsktxQAAAAAAAAAAwAAAAAAAAEYAAQAAAAAAAS8nfAAOr03buTZBMmukiq4HoizADOUR05MxABBLoP1AAAAAAAVhYm91dAAAAARob21l4NodcC97EdOM0ABgsPwUoweiLMAM5RHTkzEAEEug/UAAAAAADm1vei1zYWZlLWFib3V0AAAABGhvbWUAAAA=","docIdentifier":5},{"url":"http://www.google.co.uk/","title":"Google","ID":6,"docshellID":11,"docIdentifier":6,"children":[{"url":"about:blank","ID":7,"docshellID":12,"owner_b64":"NhAra3tiRRqhyKDUVsktxQAAAAAAAAAAwAAAAAAAAEYAAQAAAAAAAd6UctCANBHTk5kAEEug/UAHoizADOUR05MxABBLoP1AAAAAAv////8AAABQAQAAABhodHRwOi8vd3d3Lmdvb2dsZS5jby51ay8AAAAAAAAABAAAAAcAAAAQAAAAB/////8AAAAH/////wAAAAcAAAAQAAAAFwAAAAEAAAAXAAAAAQAAABcAAAABAAAAGAAAAAAAAAAY/////wAAABf/////AAAAF/////8AAAAX/////wEAAAAAAAAAAAABAAA=","docIdentifier":7,"scroll":"0,0"}],"formdata":{"#csi":"1","#hcache":"{\"BInSTfL-EtSt8QOl24nrCg\":[[69,{}],[14,{}],[60,{}],[81,{\"persisted\":true}],[42,{}],[43,{}],[83,{}],[95,{\"kfe\":{\"kfeHost\":\"clients1.google.co.uk\",\"kfeUrlPrefix\":\"/webpagethumbnail?r=2&f=2&s=300:585&query=&hl=en&gl=uk\",\"maxPrefetchConnections\":2,\"prefetch\":90,\"slowConnection\":false},\"logging\":{\"csiFraction\":0.05,\"gen204Fraction\":0.05},\"msgs\":{\"loading\":\"Still loading...\",\"mute\":\"Mute\",\"noPreview\":\"Preview not available\",\"sound\":\"Sound:\",\"soundOff\":\"off\",\"soundOn\":\"on\",\"unmute\":\"Unmute\"},\"pb\":{\"desiredHeight\":585,\"desiredWidth\":300,\"minHeight\":200,\"minWidth\":300},\"time\":{\"hoverClose\":300,\"hoverModeTimeout\":60,\"hoverOpen\":125,\"loading\":100,\"longHoverOpen\":725,\"prefetchOnLoad\":3000,\"timeout\":2500}}],[78,{}],[25,{\"m\":{\"bks\":true,\"blg\":true,\"dsc\":true,\"evn\":true,\"frm\":true,\"isch\":true,\"klg\":true,\"mbl\":true,\"nws\":true,\"plcs\":true,\"ppl\":true,\"prc\":true,\"pts\":true,\"rcp\":true,\"shop\":true,\"vid\":true},\"t\":null}],[64,{}],[105,{}],[22,{\"m_errors\":{\"32\":\"Sorry, no more results to show.\",\"default\":\"<font color=red>Error:</font> The server could not complete your request. Try again in 30 seconds.\"},\"m_tip\":\"Click for more information\"}],[77,{}],[84,{}],[99,{}],[29,{\"mcr\":5}],[92,{\"avgTtfc\":2000,\"fd\":1000,\"fl\":true,\"focus\":true,\"hpt\":250,\"kn\":true,\"mds\":\"clir,clue,dfn,evn,frim,klg,prc,rl,show,sp,sts,ww,mbl_he,mbl_hs,mbl_re,mbl_rs,mbl_sv,isch\",\"msg\":{\"dym\":\"Did you mean:\",\"gs\":\"Google Search\",\"kntt\":\"Use the up and down arrow keys to select each result. Press Enter to go to the selection.\",\"sif\":\"Search instead for\",\"srf\":\"Showing results for\"},\"odef\":true,\"ophe\":true,\"pq\":true,\"rpt\":41,\"tct\":\" ?\",\"tdur\":50}],[24,{}],[38,{}]]}"},"scroll":"0,0"}],"index":2,"hidden":false,"attributes":{"image":"http://www.google.co.uk/favicon.ico"},"storage":{"http://www.google.co.uk":{"web-v":"12_c9c918f0"}}}],"selected":1,"_closedTabs":[],"width":994,"height":688,"screenX":1650,"screenY":24,"sizemode":"normal","title":"Google"}],"selectedWindow":0,"_closedWindows":[{"tabs":[{"entries":[{"url":"about:home","title":"Mozilla Firefox Start Page","ID":0,"docshellID":5,"owner_b64":"NhAra3tiRRqhyKDUVsktxQAAAAAAAAAAwAAAAAAAAEYAAQAAAAAAAS8nfAAOr03buTZBMmukiq4HoizADOUR05MxABBLoP1AAAAAAAVhYm91dAAAAARob21l4NodcC97EdOM0ABgsPwUoweiLMAM5RHTkzEAEEug/UAAAAAADm1vei1zYWZlLWFib3V0AAAABGhvbWUAAAA="},{"url":"http://www.facebook.com/","title":"Welcome to Facebook - Log In, Sign Up or Learn More","ID":1,"docshellID":5,"docIdentifier":1,"formdata":{"//xhtml:div[#id='reg_form_box']/xhtml:table/xhtml:tbody/xhtml:tr[6]/xhtml:td[2]/xhtml:div/xhtml:div/xhtml:select":0,"//xhtml:div[#id='reg_form_box']/xhtml:table/xhtml:tbody/xhtml:tr[6]/xhtml:td[2]/xhtml:div/xhtml:div/xhtml:select[2]":0,"#sex":0,"#birthday_month":0,"#birthday_day":0,"#birthday_year":0},"scroll":"0,0"}],"index":2,"hidden":false,"attributes":{"image":"http://www.facebook.com/favicon.ico"}},{"entries":[{"url":"http://twitter.com/","title":"Twitter","ID":3,"docshellID":6,"docIdentifier":3,"children":[{"url":"http://api.twitter.com/receiver.html","ID":4,"docshellID":7,"referrer":"http://twitter.com/","docIdentifier":4,"scroll":"0,0"}],"formdata":{},"scroll":"0,0"}],"index":1,"hidden":false,"attributes":{"image":"http://twitter.com/phoenix/favicon.ico"}}],"selected":2,"_closedTabs":[],"width":994,"height":688,"screenX":1366,"screenY":307,"sizemode":"normal","cookies":[{"host":".facebook.com","value":"J4-69","path":"/","name":"lsd"},{"host":".facebook.com","value":"http%3A%2F%2Fwww.facebook.com%2F","path":"/","name":"reg_fb_gate"},{"host":".facebook.com","value":"http%3A%2F%2Fwww.facebook.com%2F","path":"/","name":"reg_fb_ref"},{"host":".facebook.com","value":"994x624","path":"/","name":"wd"},{"host":".twitter.com","value":"43838368","path":"/","name":"__utmc"},{"host":"twitter.com","value":"4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl","path":"/","name":"original_referer"},{"host":"scribe.twitter.com","value":"4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl","path":"/","name":"original_referer"},{"host":".twitter.com","value":"BAh7CToPY3JlYXRlZF9hdGwrCDoVZ%252F4vAToMY3NyZl9pZCIlODE2MGI1ZjJh%250AYmViNDMwODMxNDlkN2U5ZDg5Yjk4ZmU6B2lkIiU2N2I4YjdmNGExNWFkNzlk%250AODI0MDVjMGM1NmMzYjVhYSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6%250ARmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%253D%253D--8b0d751e9774c5cfaa61fdec567cb782aa8757dd","path":"/","name":"_twitter_sess","httponly":true},{"host":".twitter.com","value":"43838368","path":"/","name":"__utmc"},{"host":"twitter.com","value":"4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl","path":"/","name":"original_referer"},{"host":"scribe.twitter.com","value":"4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl","path":"/","name":"original_referer"},{"host":".twitter.com","value":"BAh7CToPY3JlYXRlZF9hdGwrCDoVZ%252F4vAToMY3NyZl9pZCIlODE2MGI1ZjJh%250AYmViNDMwODMxNDlkN2U5ZDg5Yjk4ZmU6B2lkIiU2N2I4YjdmNGExNWFkNzlk%250AODI0MDVjMGM1NmMzYjVhYSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6%250ARmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%253D%253D--8b0d751e9774c5cfaa61fdec567cb782aa8757dd","path":"/","name":"_twitter_sess","httponly":true}],"title":"Twitter"}],"session":{"state":"stopped","lastUpdate":1305658398727}}
and when I tried to load that with my program I got the error
Error: sessionstore.js(1): expected value
Since the file is formatted all on a single line, this meant the error could be anywhere in the file, so I ran it though a Javascript beautifier, keeping the default options, and pasted the results back into the original file and executed the program.
The formatted JSON is
{
"windows": [{
"tabs": [{
"entries": [{
"url": "about:home",
"title": "Mozilla Firefox Start Page",
"ID": 5,
"docshellID": 11,
"owner_b64": "NhAra3tiRRqhyKDUVsktxQAAAAAAAAAAwAAAAAAAAEYAAQAAAAAAAS8nfAAOr03buTZBMmukiq4HoizADOUR05MxABBLoP1AAAAAAAVhYm91dAAAAARob21l4NodcC97EdOM0ABgsPwUoweiLMAM5RHTkzEAEEug/UAAAAAADm1vei1zYWZlLWFib3V0AAAABGhvbWUAAAA=",
"docIdentifier": 5
}, {
"url": "http://www.google.co.uk/",
"title": "Google",
"ID": 6,
"docshellID": 11,
"docIdentifier": 6,
"children": [{
"url": "about:blank",
"ID": 7,
"docshellID": 12,
"owner_b64": "NhAra3tiRRqhyKDUVsktxQAAAAAAAAAAwAAAAAAAAEYAAQAAAAAAAd6UctCANBHTk5kAEEug/UAHoizADOUR05MxABBLoP1AAAAAAv////8AAABQAQAAABhodHRwOi8vd3d3Lmdvb2dsZS5jby51ay8AAAAAAAAABAAAAAcAAAAQAAAAB/////8AAAAH/////wAAAAcAAAAQAAAAFwAAAAEAAAAXAAAAAQAAABcAAAABAAAAGAAAAAAAAAAY/////wAAABf/////AAAAF/////8AAAAX/////wEAAAAAAAAAAAABAAA=",
"docIdentifier": 7,
"scroll": "0,0"
}],
"formdata": {
"#csi": "1",
"#hcache": "{\"BInSTfL-EtSt8QOl24nrCg\":[[69,{}],[14,{}],[60,{}],[81,{\"persisted\":true}],[42,{}],[43,{}],[83,{}],[95,{\"kfe\":{\"kfeHost\":\"clients1.google.co.uk\",\"kfeUrlPrefix\":\"/webpagethumbnail?r=2&f=2&s=300:585&query=&hl=en&gl=uk\",\"maxPrefetchConnections\":2,\"prefetch\":90,\"slowConnection\":false},\"logging\":{\"csiFraction\":0.05,\"gen204Fraction\":0.05},\"msgs\":{\"loading\":\"Still loading...\",\"mute\":\"Mute\",\"noPreview\":\"Preview not available\",\"sound\":\"Sound:\",\"soundOff\":\"off\",\"soundOn\":\"on\",\"unmute\":\"Unmute\"},\"pb\":{\"desiredHeight\":585,\"desiredWidth\":300,\"minHeight\":200,\"minWidth\":300},\"time\":{\"hoverClose\":300,\"hoverModeTimeout\":60,\"hoverOpen\":125,\"loading\":100,\"longHoverOpen\":725,\"prefetchOnLoad\":3000,\"timeout\":2500}}],[78,{}],[25,{\"m\":{\"bks\":true,\"blg\":true,\"dsc\":true,\"evn\":true,\"frm\":true,\"isch\":true,\"klg\":true,\"mbl\":true,\"nws\":true,\"plcs\":true,\"ppl\":true,\"prc\":true,\"pts\":true,\"rcp\":true,\"shop\":true,\"vid\":true},\"t\":null}],[64,{}],[105,{}],[22,{\"m_errors\":{\"32\":\"Sorry, no more results to show.\",\"default\":\"<font color=red>Error:</font> The server could not complete your request. Try again in 30 seconds.\"},\"m_tip\":\"Click for more information\"}],[77,{}],[84,{}],[99,{}],[29,{\"mcr\":5}],[92,{\"avgTtfc\":2000,\"fd\":1000,\"fl\":true,\"focus\":true,\"hpt\":250,\"kn\":true,\"mds\":\"clir,clue,dfn,evn,frim,klg,prc,rl,show,sp,sts,ww,mbl_he,mbl_hs,mbl_re,mbl_rs,mbl_sv,isch\",\"msg\":{\"dym\":\"Did you mean:\",\"gs\":\"Google Search\",\"kntt\":\"Use the up and down arrow keys to select each result. Press Enter to go to the selection.\",\"sif\":\"Search instead for\",\"srf\":\"Showing results for\"},\"odef\":true,\"ophe\":true,\"pq\":true,\"rpt\":41,\"tct\":\" ?\",\"tdur\":50}],[24,{}],[38,{}]]}"
},
"scroll": "0,0"
}],
"index": 2,
"hidden": false,
"attributes": {
"image": "http://www.google.co.uk/favicon.ico"
},
"storage": {
"http://www.google.co.uk": {
"web-v": "12_c9c918f0"
}
}
}],
"selected": 1,
"_closedTabs": [],
"width": 994,
"height": 688,
"screenX": 1650,
"screenY": 24,
"sizemode": "normal",
"title": "Google"
}],
"selectedWindow": 0,
"_closedWindows": [{
"tabs": [{
"entries": [{
"url": "about:home",
"title": "Mozilla Firefox Start Page",
"ID": 0,
"docshellID": 5,
"owner_b64": "NhAra3tiRRqhyKDUVsktxQAAAAAAAAAAwAAAAAAAAEYAAQAAAAAAAS8nfAAOr03buTZBMmukiq4HoizADOUR05MxABBLoP1AAAAAAAVhYm91dAAAAARob21l4NodcC97EdOM0ABgsPwUoweiLMAM5RHTkzEAEEug/UAAAAAADm1vei1zYWZlLWFib3V0AAAABGhvbWUAAAA="
}, {
"url": "http://www.facebook.com/",
"title": "Welcome to Facebook - Log In, Sign Up or Learn More",
"ID": 1,
"docshellID": 5,
"docIdentifier": 1,
"formdata": {
"//xhtml:div[#id='reg_form_box']/xhtml:table/xhtml:tbody/xhtml:tr[6]/xhtml:td[2]/xhtml:div/xhtml:div/xhtml:select": 0,
"//xhtml:div[#id='reg_form_box']/xhtml:table/xhtml:tbody/xhtml:tr[6]/xhtml:td[2]/xhtml:div/xhtml:div/xhtml:select[2]": 0,
"#sex": 0,
"#birthday_month": 0,
"#birthday_day": 0,
"#birthday_year": 0
},
"scroll": "0,0"
}],
"index": 2,
"hidden": false,
"attributes": {
"image": "http://www.facebook.com/favicon.ico"
}
}, {
"entries": [{
"url": "http://twitter.com/",
"title": "Twitter",
"ID": 3,
"docshellID": 6,
"docIdentifier": 3,
"children": [{
"url": "http://api.twitter.com/receiver.html",
"ID": 4,
"docshellID": 7,
"referrer": "http://twitter.com/",
"docIdentifier": 4,
"scroll": "0,0"
}],
"formdata": {},
"scroll": "0,0"
}],
"index": 1,
"hidden": false,
"attributes": {
"image": "http://twitter.com/phoenix/favicon.ico"
}
}],
"selected": 2,
"_closedTabs": [],
"width": 994,
"height": 688,
"screenX": 1366,
"screenY": 307,
"sizemode": "normal",
"cookies": [{
"host": ".facebook.com",
"value": "J4-69",
"path": "/",
"name": "lsd"
}, {
"host": ".facebook.com",
"value": "http%3A%2F%2Fwww.facebook.com%2F",
"path": "/",
"name": "reg_fb_gate"
}, {
"host": ".facebook.com",
"value": "http%3A%2F%2Fwww.facebook.com%2F",
"path": "/",
"name": "reg_fb_ref"
}, {
"host": ".facebook.com",
"value": "994x624",
"path": "/",
"name": "wd"
}, {
"host": ".twitter.com",
"value": "43838368",
"path": "/",
"name": "__utmc"
}, {
"host": "twitter.com",
"value": "4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl",
"path": "/",
"name": "original_referer"
}, {
"host": "scribe.twitter.com",
"value": "4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl",
"path": "/",
"name": "original_referer"
}, {
"host": ".twitter.com",
"value": "BAh7CToPY3JlYXRlZF9hdGwrCDoVZ%252F4vAToMY3NyZl9pZCIlODE2MGI1ZjJh%250AYmViNDMwODMxNDlkN2U5ZDg5Yjk4ZmU6B2lkIiU2N2I4YjdmNGExNWFkNzlk%250AODI0MDVjMGM1NmMzYjVhYSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6%250ARmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%253D%253D--8b0d751e9774c5cfaa61fdec567cb782aa8757dd",
"path": "/",
"name": "_twitter_sess",
"httponly": true
}, {
"host": ".twitter.com",
"value": "43838368",
"path": "/",
"name": "__utmc"
}, {
"host": "twitter.com",
"value": "4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl",
"path": "/",
"name": "original_referer"
}, {
"host": "scribe.twitter.com",
"value": "4bfz%2B%2BmebEkRkMWFCXm%2FCUOsvDoVeFTl",
"path": "/",
"name": "original_referer"
}, {
"host": ".twitter.com",
"value": "BAh7CToPY3JlYXRlZF9hdGwrCDoVZ%252F4vAToMY3NyZl9pZCIlODE2MGI1ZjJh%250AYmViNDMwODMxNDlkN2U5ZDg5Yjk4ZmU6B2lkIiU2N2I4YjdmNGExNWFkNzlk%250AODI0MDVjMGM1NmMzYjVhYSIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6%250ARmxhc2g6OkZsYXNoSGFzaHsABjoKQHVzZWR7AA%253D%253D--8b0d751e9774c5cfaa61fdec567cb782aa8757dd",
"path": "/",
"name": "_twitter_sess",
"httponly": true
}],
"title": "Twitter"
}],
"session": {
"state": "stopped",
"lastUpdate": 1305658398727
}
}
The error
Error: sessionstore.js(179): expected value
now identifies the fault as being on the third-last line, the one that reads "lastUpdate": 1305658398727. From what I've read about the JSON format, this sounds to me like a comma or bracket is missing from this line, but this is a file that has been produced my Mozilla to work with Firefox, and I don't believe that they would make a mistake like that, so I am lead to believe that there is a problem with the JSON parser in Boost. Can anyone please confirm if this is the case, or if I'm the one doing something wrong?
I think the problem is this value is bigger than an int or a double. I don't know what data type uses BOOST JSON for reading numbers. To test this, just change the number to be a string and parse it again. In the standard, numbers are not limited, but you have to select a data type to represent them, and maybe they selected double, clearly not enough for this number. I'll take a look to see if you can configure the type used for numbers.
EDIT:
Looking again at the implementation, the "number" rule is implemented using Spirit as follows:
number
= strict_real_p
| int_p
;
Looking at Spirit strict_real_p uses double as the underlying type, and int_p actually uses an int.
The bad news is that, for what I see in the code, this is not configurable, so you have to change the JSON to be interpreted.
After receiving answers from Diego Sevilla and c-smile, I did a bit of Googling to figure out how I would incorporate their suggestions into Boost, since changing the JSON file unfortunately isn't an option in my case, and I came across this ticket on the Boost bug tracker that describes my exact problem. It has since been fixed and released with Boost 1.45. I, however, am using version 1.42 from the Ubuntu repositories, so will need to install the newer version manually.
As Diego said that is because 1305658398727 does not fit into neither strict_real_p nor int_p production.
I suspect you will need either other JSON parser or to modify Spirit definitions by yourself.
Either like this:
number
= strict_real_p
| int_p
| int64_p
;
or just as:
number
= real_p;
Ideally date/time in JSON should be presented by strings in ISO format. In this case you will not have such problems. I suspect that data there is just a number of milliseconds since 1970-01-01 (JavaScript Date.valueOf())