-
-
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.csv
which tells you which assets were replaced.