-
-
Save joshday/1881c2bb7c781027bfcb0c598de0f8b5 to your computer and use it in GitHub Desktop.
| # Edit Pluto (in place!) to run in an air-gapped environment | |
| # Editing a package after it's installed is bad. But hey, this works. | |
| # Before running this script, you can instantiate a new depot to avoid | |
| # contaminating your main depot. Something like: | |
| # | |
| # push!(empty!(DEPOT_PATH), "my/new/depot/path") | |
| # using Pkg | |
| # Pkg.activate("my/project/path") | |
| # Pkg.instantiate() | |
| using Pluto, DelimitedFiles | |
| pluto_root(args...) = abspath(joinpath(pathof(Pluto), "..", "..", args...)) | |
| function _replace(file, old_new::Pair) | |
| old, new = old_new | |
| sed = Sys.isapple() ? ["sed", "-i", ""] : ["sed", "-i"] | |
| run(`$sed $("s|$old|$new|g") $file`) | |
| end | |
| frontend = pluto_root("frontend") | |
| assets = pluto_root("frontend", "offline_assets") | |
| mkpath(assets) | |
| # find all lines that contain `jsdelivr`, the CDN that delivers assets to Pluto | |
| lines = split(read(`grep -r "jsdelivr" $frontend`, String), '\n') | |
| # place all CDN urls into `replaced_assets` | |
| replaced_assets = [] | |
| for line in lines | |
| match = findfirst(r"((?<=\")https:\/\/[^\"]*)|((?<=\()https:\/\/[^\)]*)", line) | |
| if isnothing(match) | |
| @warn "No match found for line: $line" | |
| else | |
| url = line[match] | |
| push!(replaced_assets, url) | |
| pluto_file = line[1:findfirst(':', line) - 1] | |
| _replace(pluto_file, url => "/offline_assets/$(basename(url))") | |
| end | |
| end | |
| writedlm(joinpath(@__DIR__, "assets.csv"), replaced_assets) | |
| dir = pluto_root("frontend", "offline_assets") | |
| for url in readlines(joinpath(@__DIR__, "assets.csv") ) | |
| @info "Downloading: $url" | |
| file = touch(joinpath(dir, basename(url))) | |
| download(url, file) | |
| end |
This script can't run in Pluto v0.14.7.
$)─> julia offline_pluto.jl ┌ Warning: No match found for line: ~/.julia/packages/Pluto/D9HrI/frontend/common/Binder.js: fetch(https://cdn.jsdelivr.net/gh/fonsp/pluto-usage-counter@1/binder-start.txt?skip_sw`).catch(() => {})
└ @ Main /software/offline_pluto.jl:34/.julia/packages/Pluto/D9HrI/frontend/sw.js:const allowList = ["www.gstatic.com", "fonts.gstatic.com", "fonts.googleapis.com", "cdn.jsdelivr.net", "cdnjs.cloudflare.com", "unpkg.com"]
┌ Warning: No match found for line:
└ @ Main ~/software/offline_pluto.jl:34
┌ Warning: No match found for line: ~/.julia/packages/Pluto/D9HrI/frontend/components/CellOutput.js: path: (mode) => https://cdn.jsdelivr.net/npm/codemirror@5.60.0/mode/${mode}/${mode}.min.js,
└ @ Main ~/software/offline_pluto.jl:34
┌ Warning: No match found for line: ~/.julia/packages/Pluto/D9HrI/frontend/components/Editor.js: fetch(https://cdn.jsdelivr.net/gh/fonsp/pluto-usage-counter@1/article-view.txt?skip_sw).catch(() => {})
└ @ Main ~/software/offline_pluto.jl:34
┌ Warning: No match found for line:
└ @ Main ~/software/offline_pluto.jl:34
ERROR: LoadError: UndefVarError: here not defined
Stacktrace:
[1] top-level scope
@ ~/software/offline_pluto.jl:45
in expression starting at ~/software/offline_pluto.jl:45
`
Could you update?
I can't reproduce. What platform are you using?
Never mind...I copied and pasted this from a larger script and I missed a function definition. It's updated now.
This script also saves
assets.csvwhich tells you which assets were replaced.