Skip to content

Instantly share code, notes, and snippets.

@calraith
Created May 23, 2018 03:20
Show Gist options
  • Save calraith/5ea698d022dfe77d3927e75af7cdea75 to your computer and use it in GitHub Desktop.
Save calraith/5ea698d022dfe77d3927e75af7cdea75 to your computer and use it in GitHub Desktop.
This is meant to be a PowerShell alternative to https://gist.github.com/derjanb/9f6c10168e63c3dc3cf0 for Windows users unable to compile the leveldb Python module.
# Copy your Tampermonkey storage.js into the same directory as this script.
# It'll extract the user scripts from storage.js and write them as .user.js files
# in the current working directory.
add-type -as System.Web.Extensions
$JSON = new-object Web.Script.Serialization.JavaScriptSerializer
$obj = $JSON.DeserializeObject((gc storage.js))
foreach ($key in $obj.keys) {
foreach ($val in $obj[$key].value) {
if ($val -match "\r?\n//\s+@name\s+(.+)\r?\n") {
$val | out-file ("{0}.user.js" -f $matches[1])
}
}
}
@BangDroid
Copy link

Exception calling "DeserializeObject" with "1" argument(s): "Invalid JSON primitive: ."
At E:*\Users*\AppData\Local\Google\Chrome\User
Data\Default\Extensions\dhdgffkkebhmkfjojejmpbldmpobfkfo\4.5_0\extract_tampermonkey_scripts.ps1:7 char:1

  • $obj = $JSON.DeserializeObject((gc storage.js))
  •   + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
      + FullyQualifiedErrorId : ArgumentException
    

@calraith
Copy link
Author

calraith commented May 28, 2018

@BangDroid Seems to be a problem with your storage.js, or at least something the PowerShell deserializer doesn't like. I wonder what would happen if you copypasted the contents of your storage.js into the JSON validator at jsonlint.com? Or maybe one of your script names includes a character that would be invalid in a filename? I just tested the script again with my own storage.js and it works, but I don't have any sanity checking on the JSON or file writing at all.

@calraith
Copy link
Author

calraith commented Jun 5, 2018

if you can't get this PowerShell script to work, I also wrote a JSON serializer / deserializer for gawk.

  1. Download the gawk binaries from the ezwinports project. Extract to a subdirectory. (Note: the GnuWin32 port of gawk will not work. The JSON script requires at least gawk version 4.)
  2. Save my gawk script.
  3. Modify the script and replace the END{...} section with the following code:
END {
    deserialize(json, obj)

    for (i in obj) {
        if (!isarray(obj[i]) || !isarray(obj[i]["value"])) continue
        header = obj[i]["value"]["header"]
        if (!header) continue
        textContent = obj[i]["value"]["textContent"]
        match(header, /@name\s+([^\n]+)/, script)
        gsub(/\s+/, "_", script[1])
        gsub(/[\\\/:\*\?"<>|]/, "", script[1])
        print textContent > script[1] ".user.js"
    }
}
  1. Open a cmd prompt or PowerShell window. cd to the directory where you want to save your user.js files
  2. Run this command:
\path\to\gawkdir\bin\gawk.exe -f \path\to\json.awk \path\to\storage.js

@Remonell
Copy link

@calraith I tried to run your gawk and did get following errors:

http://prntscr.com/jyi8hx

I already inserted before and after a square bracket a space because a post on stackoverflow suggested that. Do you have any idea why it is still not working?

@calraith
Copy link
Author

calraith commented Jun 27, 2018

@Cappuccino90 I think I see from your screenshot what's going on. The version of gawk supplied with GnuWin32 is ancient (last updated in 2008 I think). My code requires at least gawk version 4 I believe. That's why I recommended using the ezwinports build.

FWIW, arrayname["parent"]["child"] is the appropriate format for a multi-depth array in awk. Don't let anyone talk you into inserting extra spaces.

@Remonell
Copy link

Remonell commented Jul 12, 2018

@calraith Thanks for the response. Sadly it is still not working. It does run the gawk command though without any printed out errors. http://prntscr.com/k5hej4
I downloaded gawk-4.2.1-w32-bin.zip from the link you provided. I hope that was the right package.
This is the content of my json.awk file: https://pastebin.com/U4SBnmNN

After the execution the storage.js file does not seem to have been altered in any form. Also the powershell script still throws the same error: http://prntscr.com/k5hiek Also tried to run powershell as administrator.
Sorry that some of the texts are in german.

Do you have any idea why it is not working?

Kind regards

@calraith
Copy link
Author

@Cappuccino90: Would you care to PM me on Pastebin? My username there is rojo. If you like, you can create a private paste of your storage.js then PM me the URL and I'll see if I can help you figure out what's wrong with it. Or if you prefer, try pasting the contents of your storage.js into a JSON validator. The error message in your screenshot, Ausnahme beim Aufrufen von "DeserializeObject" mit 1 Argument(en): "Ungultiger JSON-Primitiv: .", hints that the reason you're having trouble extracting the .user.js files is due to invalid JSON, like maybe your storage.js file is corrupt.

@Remonell
Copy link

Remonell commented Aug 8, 2018

My storage.js file begins like the following:
(function() { Registry.require(["promise"], function() { var f = rea.FEATURES,

JSONLint validator also tells me that the very first character is faulty. The open bracket.
@calraith How does your storage.js begin?

@michaelts1
Copy link

TY so much!
I wish there was an upvote in github to let more users know about this!

@HatScripts
Copy link

HatScripts commented Feb 12, 2019

@calraith Where is this so-called Tampermonkey storage.js file located? The one I found at %appdata%\Opera Software\Opera Stable\Extensions\dhdgffkkebhmkfjojejmpbldmpobfkfo\4.7.54_0\storage.js is just 13 KB of JavaScript, not JSON. So I get the same error as @BangDroid and @Remonell.

@Aceralon
Copy link

Aceralon commented Aug 1, 2020

@calraith Where is this so-called Tampermonkey storage.js file located? The one I found at %appdata%\Opera Software\Opera Stable\Extensions\dhdgffkkebhmkfjojejmpbldmpobfkfo\4.7.54_0\storage.js is just 13 KB of JavaScript, not JSON. So I get the same error as @BangDroid and @Remonell.

I guess this script did nothing. The actual scripts should be in User Data\Default\Local Extension Settings and stored in db not some random storage.js.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment