Adding entries to JSON Bookmarks file with powershell - json

So i have reviewed and tested the code in Combining the bookmark JSON files from Chome and Edge Chromium into one file using PowerShell? which was very handy to understand some things about JSON and powershell.
I have Chrome's and Edge's bookmarks exported into 2 discreet files by using the code in the link.
Now the problem i have is that if i combine the 2 it is changing the format for the new bookmark file is not properly readable by edge.
Ideally what I need to do is re-write the file adding entries to specific nodes (i am not sure about the JSON nomeclature so please excuse my ignorance)
So an Edge/Chrome bookmark file looks like:
{
"checksum": "555e69b0181a1a30d58cc3fff59f7dad",
"roots": {
"bookmark_bar": {
"children": [ {
"date_added": "13301408662223632",
"guid": "7b8047d6-eb01-4629-a960-a81307fbb0b0",
"id": "17",
"name": "Home - BBC News",
"type": "url",
"url": "https://www.bbc.co.uk/news"
}, {
"date_added": "13301408702331979",
"guid": "eb1d3e92-eb5a-4011-a6ea-e6f15ec9a58a",
"id": "20",
"name": "Your stream on SoundCloud",
"type": "url",
"url": "https://soundcloud.com/stream"
} ],
"date_added": "13301408646379132",
"date_modified": "13301408702331979",
"guid": "0bc5d13f-2cba-5d74-951f-3f233fe6c908",
"id": "1",
"name": "Bookmarks bar",
"type": "folder"
},
"other": {
"children": [ ],
"date_added": "13301408646379134",
"date_modified": "0",
"guid": "82b081ec-3dd3-529c-8475-ab6c344590dd",
"id": "2",
"name": "Other bookmarks",
"type": "folder"
},
"synced": {
"children": [ ],
"date_added": "13301408646379137",
"date_modified": "0",
"guid": "4cf2e351-0e85-532b-bb37-df045d8f8d0f",
"id": "3",
"name": "Mobile bookmarks",
"type": "folder"
}
},
"version": 1
}
i would like to be able to add to nodes under "bookmark_bar" and "other":
So my code from reading these 2 files and stroring them as JSON is:
$data1 = Get-Content $BackupStore/Bookmarks-chrome.json | ConvertFrom-Json
$data2 = Get-Content $BackupStore/Bookmarks-edge.json | ConvertFrom-Json
$store1=$data1.roots
$store2=$data2.roots
How should i proceed now combining them in their respective nodes?

Related

Combining the bookmark JSON files from Chome and Edge Chromium into one file using PowerShell?

We are migrating from Chrome to Edge Chromium (and when Microsoft puts the final nail into the IE 11 coffin from IE 11 as well). This is being done when PCs are being replaced.
We are using USMT to copy users files over. So the old computer may or may not have Chrome, but if it does, I'd like to copy the bookmark files. If it has Edge installed too (most do), I'd like to copy those bookmarks too. When restoring the USMT data, I'd like to add a step to our restore script that merges the results of both of the bookmark files into one JSON file and import it into Edge Chromium (I think I can just plop the "Bookmarks" file into "C:\Users$UserID\AppData\Local\Microsoft\Edge\User Data\Default").
I have these three functions that get called in other parts of the script:
Function Backup-ChromeBookmarks {
$pathToChromeJsonFile = -join("C:\Users\", $UserID, "\AppData\local\Google\Chrome\User Data\Default\Bookmarks")
$global:chromeBookmarkExists = Test-Path $pathToChromeJsonFile
if ($chromeBookmarkExists -eq $true){
Copy-Item -Path $pathToChromeJsonFile -Destination $BackupStore/Bookmarks-chrome.json
}
}
Function Backup-EdgeBookmarks {
$pathToEdgeJsonFile = -join("C:\Users\", $UserID, "\AppData\Local\Microsoft\Edge\User Data\Default\Bookmarks")
$global:edgeBookmarkExists = Test-Path $pathToEdgeJsonFile
if ($edgeBookmarkExists -eq $true){
Copy-Item -Path $pathToEdgeJsonFile -Destination $BackupStore/Bookmarks-edge.json
}
}
Function Combine-Bookmarks {
# referenced https://www.jonathanmedd.net/2020/04/combine-two-json-files-with-powershell.html
#https://web.archive.org/web/20200517182000/https://www.jonathanmedd.net/2020/04/combine-two-json-files-with-powershell.html
if($chromeBookmarkExists -eq $true -And $edgeBookmarkExists -eq $true){
$data1 = Get-Content $BackupStore/Bookmarks-chrome.json -Raw | ConvertFrom-Json
$data2 = Get-Content $BackupStore/Bookmarks-edge.json -Raw | ConvertFrom-Json
$data1.psobject.Properties | ForEach-Object {
$data2 | Add-Member -MemberType $_.MemberType -Name $_.Name -Value $_.Value -Force
}
#($data2) | ConvertTo-Json | Out-File $BackupStore/Bookmarks
}
}
It works to copy the "Bookmarks" files from Chrome and Edge, but when it combines them and writes the file, this is all the contents are:
"checksum": "0f9bf8e97b9ac6cd3654c15c673b8cb8",
"roots": {
"bookmark_bar": {
"children": " ",
"date_added": "13252082948039886",
"date_modified": "13268156238031255",
"guid": "0bc5d13f-2cba-5d74-951f-3f233fe6c908",
"id": "1",
"name": "Bookmarks bar",
"type": "folder"
},
"other": {
"children": "",
"date_added": "13252082948040297",
"date_modified": "0",
"guid": "82b081ec-3dd3-529c-8475-ab6c344590dd",
"id": "2",
"name": "Other bookmarks",
"type": "folder"
},
"synced": {
"children": "",
"date_added": "13252082948040301",
"date_modified": "0",
"guid": "4cf2e351-0e85-532b-bb37-df045d8f8d0f",
"id": "3",
"name": "Mobile bookmarks",
"type": "folder"
}
},
"version": 1
}
Does anyone have any idea what I am doing wrong with merging the two JSON files? I don't have a lot of experience with this and would appreciate any feedback.
Please let me know if I'm missing any info. Thanks!
Here are some random bookmark lists from Chrome and Edge for sample data:
Chrome
"checksum": "0e3450f30154cec188275de0e1eed2a5",
"roots": {
"bookmark_bar": {
"children": [ {
"date_added": "13282342589274138",
"guid": "dff3def7-9693-443c-a44c-2b1047687b33",
"id": "5",
"name": "Google News",
"type": "url",
"url": "https://news.google.com/topstories?hl=en-CA&gl=CA&ceid=CA:en"
}, {
"children": [ {
"date_added": "13282342602339055",
"guid": "3a6114ed-d13a-491e-a049-d47a174a349b",
"id": "7",
"name": "reddit - Google Search",
"type": "url",
"url": "https://www.google.com/search?q=reddit&oq=reddit&aqs=chrome..69i57j46i131i199i433i465i512j0i131i433i512l3j0i131i433j0i131i433i512l3.1205j0j7&sourceid=chrome&ie=UTF-8"
}, {
"date_added": "13282342613505854",
"guid": "0da478c1-a91b-4af9-80db-cae8dc6927c0",
"id": "8",
"name": "Reddit - Dive into anything",
"type": "url",
"url": "https://www.reddit.com/"
}, {
"date_added": "13282342620306591",
"guid": "b0311e2e-a41f-47fa-a1ef-214dd3964729",
"id": "9",
"name": "Facebook - Log In or Sign Up",
"type": "url",
"url": "https://www.facebook.com/"
}, {
"date_added": "13282342631549806",
"guid": "a06637af-50be-458e-95bc-730ffc1cda36",
"id": "10",
"name": "Instagram",
"type": "url",
"url": "https://www.instagram.com/?hl=en"
} ],
"date_added": "13282342597429656",
"date_modified": "13282342644382518",
"guid": "a5b18126-11f7-40df-809f-2d96f311f1f6",
"id": "6",
"name": "Test Folder",
"type": "folder"
}, {
"date_added": "13282342644382518",
"guid": "39ef0ac5-b70c-406e-acea-96c3f90935ef",
"id": "11",
"name": "Dogpile.com",
"type": "url",
"url": "https://www.dogpile.com/"
}, {
"date_added": "13282342655028948",
"guid": "d152f027-2aae-47b1-bae6-f9d7e617b639",
"id": "12",
"name": "Ask.com - What's Your Question?",
"type": "url",
"url": "https://www.ask.com/"
} ],
"date_added": "13282342511050735",
"date_modified": "13282342655028948",
"guid": "0bc5d13f-2cba-5d74-951f-3f233fe6c908",
"id": "1",
"name": "Bookmarks bar",
"type": "folder"
},
"other": {
"children": [ ],
"date_added": "13282342511050739",
"date_modified": "0",
"guid": "82b081ec-3dd3-529c-8475-ab6c344590dd",
"id": "2",
"name": "Other bookmarks",
"type": "folder"
},
"synced": {
"children": [ ],
"date_added": "13282342511050740",
"date_modified": "0",
"guid": "4cf2e351-0e85-532b-bb37-df045d8f8d0f",
"id": "3",
"name": "Mobile bookmarks",
"type": "folder"
}
},
"version": 1
}
Edge
{
"checksum": "c26640ae81258f8bb73935ccd2bb1e91",
"roots": {
"bookmark_bar": {
"children": [ {
"date_added": "13282342518391441",
"guid": "00f514ec-8d15-45b1-9c26-ba258d59c688",
"id": "9",
"name": "Google News",
"show_icon": false,
"source": "user_add",
"type": "url",
"url": "https://news.google.com/topstories?hl=en-CA&gl=CA&ceid=CA:en"
}, {
"date_added": "13282342527623442",
"guid": "f690f411-6f29-4e22-bee4-d57b225a9287",
"id": "10",
"name": "Stack Overflow - Where Developers Learn, Share, & Build Careers",
"show_icon": false,
"source": "user_add",
"type": "url",
"url": "https://stackoverflow.com/"
}, {
"children": [ {
"date_added": "13282342544239807",
"guid": "bf6d87ae-9cd1-4d02-b2de-5083e9b487f1",
"id": "12",
"name": "Amazon.ca: Low Prices – Fast Shipping – Millions of Items",
"show_icon": false,
"source": "user_add",
"type": "url",
"url": "https://www.amazon.ca/"
}, {
"date_added": "13282342551951302",
"guid": "d504da5d-4217-4a79-998c-f3dd5b0c95e0",
"id": "13",
"name": "Best Buy: Shop Online For Deals & Save | Best Buy Canada",
"show_icon": false,
"source": "user_add",
"type": "url",
"url": "https://www.bestbuy.ca/en-ca"
}, {
"date_added": "13282342564797804",
"guid": "cad2d5d7-c72e-477e-854a-d58df397574c",
"id": "15",
"name": "Laptops, Desktops, Tablets, Computer Components, Printers, TVs, Video Games & Appliances - Canada Computers & Electronics",
"show_icon": false,
"source": "user_add",
"type": "url",
"url": "https://www.canadacomputers.com/"
} ],
"date_added": "13282342538649786",
"date_modified": "13282342564797804",
"guid": "3616a33e-7bf6-47de-8142-673cc19f6d64",
"id": "11",
"name": "Shopping",
"source": "unknown",
"type": "folder"
} ],
"date_added": "13282342417969383",
"date_modified": "13282342544239807",
"guid": "0bc5d13f-2cba-5d74-951f-3f233fe6c908",
"id": "1",
"name": "Favorites bar",
"source": "unknown",
"type": "folder"
},
"other": {
"children": [ ],
"date_added": "13282342417969428",
"date_modified": "0",
"guid": "82b081ec-3dd3-529c-8475-ab6c344590dd",
"id": "2",
"name": "Other favorites",
"source": "unknown",
"type": "folder"
},
"synced": {
"children": [ ],
"date_added": "13282342417969430",
"date_modified": "0",
"guid": "4cf2e351-0e85-532b-bb37-df045d8f8d0f",
"id": "3",
"name": "Mobile favorites",
"source": "unknown",
"type": "folder"
}
},
"version": 1
}
As #zetta42 points out, it is likely that you just need to add more depth:
#($data2) | ConvertTo-Json -Depth 10 | Out-File $BackupStore/Bookmarks
as well as overwriting the roots property (not actually merging).
However, from a user experience you may want to consider another update. Right now if the two contain bookmarks of the same name, your intended merge logic will overwrite one with the other. A user (you) may be a whole lot happier knowing which browser a given bookmark came from and can easily re-organize from within the new browser (or, since I am not familiar with it, hopefully it does) if not desired. So I would suggest grabbing the the two bookmarks and putting them under their own folders in the new bookmarks. Something like the following:
Function Combine-Bookmarks {
# referenced https://www.jonathanmedd.net/2020/04/combine-two-json-files-with-powershell.html
#https://web.archive.org/web/20200517182000/https://www.jonathanmedd.net/2020/04/combine-two-json-files-with-powershell.html
if($chromeBookmarkExists -eq $true -And $edgeBookmarkExists -eq $true){
$data1 = Get-Content $BackupStore/Bookmarks-chrome.json -Raw | ConvertFrom-Json
$data2 = Get-Content $BackupStore/Bookmarks-edge.json -Raw | ConvertFrom-Json
$dataNew = #{
'roots'=#{'Chrome'=$data1.Roots; 'IE'=$data2.Roots}
#whatever the structure of the new json file should be
}
$dataNew | ConvertTo-Json -Depth 10 | Out-File $BackupStore/Bookmarks_new.json
}
}
Also you can either leave a folder blank if they don't have that browser, or you can exclude it from the $dataNew (by using a bit of different syntax I don't recall). Right now it will only attempt a merge if both exist.

Parsing Git Json with Regular Express

I am taking a Github json file and parsing it with Java's regular expression library JsonPath. I am having a problem parsing arrays that do not have labels.
I need to send a email every time a particular file is changed in our repository.
Here is the Git Json:
{
"trigger": "push",
"payload": {
"type": "GitPush",
"before": "xxxxxxxx",
"after": "yyyyyyyy",
"branch": "branch-name",
"ref": "refs/heads/branch-name",
"repository": {
"id": 42,
"name": "repo",
"title": "repo",
"type": "GitRepository"
},
"beanstalk_user": {
"type": "Owner",
"id": 42,
"login": "username",
"email": "user#example.org",
"name": "Name Surname"
},
"commits": [
{
"type": "GitCommit",
"id": "ffffffff",
"message": "Important changes.",
"branch": "branch-name",
"author": {
"name": "Name Surname",
"email": "user#example.org"
},
"beanstalk_user": {
"type": "Owner",
"id": 42,
"login": "username",
"email": "user#example.org",
"name": "Name Surname"
},
"changed_files": {
"added": [
"NEWFILE",
],
"deleted": [
"Gemfile",
"NEWFILE"
],
"modified": [
"README.md",
"NEWFILE"
],
"copied": [
]
},
"changeset_url": "https://subdomain.github.com/repository-name/changesets/ffffffff",
"committed_at": "2014/08/18 13:30:29 +0000",
"parents": [
"afafafaf"
]
}
]
}
}
This is the expression I am using: to get the commits
$..changed_files
This return the whole changed files part but I can not explicitly choose the name "NEWFILE"
I tried
$..changed_files.*[?(#.added == "NEWFILE")]
$..changed_files.*[?(#.*== "NEWFILE")]
It just returns a empty array.
I just want it to return Newfile and what type of change. Any Ideas?
You can use the following JsonPath to retrieve the commits which list "NEWFILE" as an added file :
$.payload.commits[?(#.changed_files.added.indexOf("NEWFILE") != -1)]

Compare 2 cucumber JSON reports with ruby

The problem is: I have 2 cucumber test reports in JSON format
I need to remove redundant key-value pairs from those reports and compare them, but I can't understand how to remove the unnecessary data from those 2 jsons because of their structure after JSON.parse (array or hash with many nested arrays/hashes). Please advice if there are some gems or known solutions to do this
JSON structure is e.g. :
[
{
"uri": "features/home_screen.feature",
"id": "as-a-user-i-want-to-explore-home-screen",
"keyword": "Feature",
"name": "As a user I want to explore home screen",
"description": "",
"line": 2,
"tags": [
{
"name": "#home_screen",
"line": 1
}
],
"elements": [
{
"keyword": "Background",
"name": "",
"description": "",
"line": 3,
"type": "background",
"before": [
{
"match": {
"location": "features/step_definitions/support/hooks.rb:1"
},
"result": {
"status": "passed",
"duration": 505329000
}
}
],
"steps": [
{
"keyword": "Given ",
"name": "I click OK button in popup",
"line": 4,
"match": {
"location": "features/step_definitions/registration_steps.rb:91"
},
"result": {
"status": "passed",
"duration": 2329140000
}
},
{
"keyword": "And ",
"name": "I click Allow button in popup",
"line": 5,
"match": {
"location": "features/step_definitions/registration_steps.rb:96"
},
"result": {
"status": "passed",
"duration": 1861776000
}
}
]
},
Since you are asking for a gem, you might try iteraptor I have created exactly for this kind of tasks.
It allows iterating, mapping and reducing the deeply nested structures. For instance, to filter out all the keys called "name" on all levels, you might do:
input.iteraptor.reject(/name/)
The more detailed description might be found on the github page linked above.

D3js pack-layout visualization of generated json file does not work

A friend wrote a program in VBA, which generates a json data. I am trying to visualize that data via the pack-layout. We extracted the rules by what the json data is being created from the json data here: http://bl.ocks.org/mbostock/7607535
I went through the data many times myself, I just can't seem to find the problem why it is not being visualized. The browser console claims a problem in line 33 with the token "]" but in my eyes the parenthesis are right and I can't seem to find another mistake.
The visualization works properly with the data from where we extracted the rules.
The question now is, which mistake in the json file prevents the code from being visualized?
Would be amazing if somebody can see this, since we cannot see it. Thanks in advance!
The generated json data looks like this:
{
"name": "While",
"children": [
{"name": "While", "size": 27},
{
"name": "If",
"children": [
{"name": "If", "size": 22},
{
"name": "If",
"children": [
{"name": "If", "size": 3}
]
},
{
"name": "If",
"children": [
{"name": "If", "size": 3}
]
},
{
"name": "If",
"children": [
{"name": "If", "size": 3}
]
},
{
"name": "If",
"children": [
{"name": "If", "size": 3}
]
},
]
},
]
}
You have two commas(,) at the end of some arrays within that JSON of yours - that makes it invalid and prone to errors.
Just edit it and it will work. Use https://jsonformatter.curiousconcept.com/ to check.
The error lies with the script that generates it :)
Here's the fixed version of your JSON:
{
"name": "While",
"children": [{
"name": "While",
"size": 27
}, {
"name": "If",
"children": [{
"name": "If",
"size": 22
}, {
"name": "If",
"children": [{
"name": "If",
"size": 3
}]
}, {
"name": "If",
"children": [{
"name": "If",
"size": 3
}]
}, {
"name": "If",
"children": [{
"name": "If",
"size": 3
}]
}, {
"name": "If",
"children": [{
"name": "If",
"size": 3
}]
}]
}]
}

How to Index & Search Nested Json in Solr 4.9.0

I want to index & search nested json in solr. Here is my json code
{
"id": "44444",
"headline": "testing US",
"generaltags": [
{
"type": "person",
"name": "Jayalalitha",
"relevance": "0.334",
"count": 1
},
{
"type": "person",
"name": "Kumar",
"relevance": "0.234",
"count": 1
}
],
"socialtags": {
"type": "SocialTag",
"name": "US",
"importance": 2
},
"topic": {
"type": "Topic",
"name": "US",
"score": "0.936"
}
}
When I try to Index, I'm getting the error "Error parsing JSON field value. Unexpected OBJECT_START"
When we tried to use Multivalued Field & index, we couldn't able to search using the multivalued field? Its returning "Undefined Field"
Also Please advice if I need to do any changes in schema.xml file?
You are nesting child documents within your document. You need to use the proper syntax for nested child documents in JSON:
[
{
"id": "1",
"title": "Solr adds block join support",
"content_type": "parentDocument",
"_childDocuments_": [
{
"id": "2",
"comments": "SolrCloud supports it too!"
}
]
},
{
"id": "3",
"title": "Lucene and Solr 4.5 is out",
"content_type": "parentDocument",
"_childDocuments_": [
{
"id": "4",
"comments": "Lots of new features"
}
]
}
]
Have a look at this article which describes JSON child documents and block joins.
Using the format mentioned by #qux you will face "Expected: OBJECT_START but got ARRAY_START at [16]",
"code": 400
as when JSON starting with [....] will parsed as a JSON array
{
"id": "44444",
"headline": "testing US",
"generaltags": [
{
"type": "person",
"name": "Jayalalitha",
"relevance": "0.334",
"count": 1
},
{
"type": "person",
"name": "Kumar",
"relevance": "0.234",
"count": 1
}
],
"socialtags": {
"type": "SocialTag",
"name": "US",
"importance": 2
},
"topic": {
"type": "Topic",
"name": "US",
"score": "0.936"
}
}
The above format is correct.
Regarding searching. Kindly use the index to search for the elements of the JSON array.
The workaround for this can be keeping the whole JSON object inside other JSON object and the indexing it
I was suggesting to keep the whole data inside another JSON object. You can try the following way
{
"data": [
{
"id": "44444",
"headline": "testing US",
"generaltags": [
{
"type": "person",
"name": "Jayalalitha",
"relevance": "0.334",
"count": 1
},
{
"type": "person",
"name": "Kumar",
"relevance": "0.234",
"count": 1
}
],
"socialtags": {
"type": "SocialTag",
"name": "US",
"importance": 2
},
"topic": {
"type": "Topic",
"name": "US",
"score": "0.936"
}
}
]
}
see the syntax in http://yonik.com/solr-nested-objects/
$ curl http://localhost:8983/solr/demo/update?commitWithin=3000 -d '
[
{id : book1, type_s:book, title_t : "The Way of Kings", author_s : "Brandon Sanderson",
cat_s:fantasy, pubyear_i:2010, publisher_s:Tor,
_childDocuments_ : [
{ id: book1_c1, type_s:review, review_dt:"2015-01-03T14:30:00Z",
stars_i:5, author_s:yonik,
comment_t:"A great start to what looks like an epic series!"
}
,
{ id: book1_c2, type_s:review, review_dt:"2014-03-15T12:00:00Z",
stars_i:3, author_s:dan,
comment_t:"This book was too long."
}
]
}
]'
supported from solr 5.3