# IPFS pre-commit hook: upload local media to Pinata, rewrite URLs in markdown
# Usage: nu nu/ipfs.nu <graph-path>
# Reads PINATA_JWT and PINATA_GATEWAY from ~/.config/cyber/env
def main [graph_path: string] {
let env_file = ($"($env.HOME)/.config/cyber/env")
if not ($env_file | path exists) {
print "No ~/.config/cyber/env file found, skipping IPFS upload"
print "Create it with: PINATA_JWT=<your-jwt> and PINATA_GATEWAY=<your-gateway>"
return
}
# Parse env file
let env_vars = (open $env_file | lines | where {|l| $l =~ '=' and not ($l | str starts-with '#')} | each {|l|
let parts = ($l | split row '=' | collect)
let key = ($parts | first | str trim)
let val = ($parts | skip 1 | str join '=' | str trim)
{key: $key, val: $val}
} | reduce -f {} {|it, acc| $acc | insert $it.key $it.val})
let jwt = ($env_vars | get -o PINATA_JWT | default '')
let gateway = ($env_vars | get -o PINATA_GATEWAY | default '')
if ($jwt | is-empty) or ($gateway | is-empty) {
print "PINATA_JWT or PINATA_GATEWAY not set in ~/.config/cyber/env, skipping"
return
}
# Find staged .md files that reference assets/
let staged = (git diff --cached --name-only --diff-filter=ACM | lines | where {|f| $f =~ '\.md$'})
if ($staged | is-empty) {
return
}
# Collect all assets/ references from staged files
let refs = ($staged | each {|f|
let path = ([$graph_path $f] | path join)
if ($path | path exists) {
open $path | lines | each {|l|
$l | parse -r 'media/[^)\s"]+\.(png|jpg|jpeg|gif|webp|svg)' | get capture0?
} | flatten
}
} | flatten | where {|r| $r != null} | uniq)
if ($refs | is-empty) {
return
}
let asset_paths = ($staged | each {|f|
let path = ([$graph_path $f] | path join)
if ($path | path exists) {
open $path | parse -r '(media/[^)\s"]+\.(?:png|jpg|jpeg|gif|webp|svg))' | get capture0
}
} | flatten | uniq)
if ($asset_paths | is-empty) {
return
}
print $"Found ($asset_paths | length) media references in staged files"
mut rewrites = []
for asset in $asset_paths {
let full_path = ([$graph_path $asset] | path join)
if not ($full_path | path exists) {
print $" SKIP: ($asset) โ file not found"
continue
}
# Upload to Pinata
print $" Uploading ($asset)..."
let resp = (http post
--content-type multipart/form-data
--headers [Authorization $"Bearer ($jwt)"]
https://api.pinata.cloud/pinning/pinFileToIPFS
{file: (open $full_path --raw)}
)
let cid = ($resp | get -o IpfsHash | default '')
if ($cid | is-empty) {
print $" WARNING: Failed to upload ($asset)"
continue
}
let ipfs_url = $"($gateway)/ipfs/($cid)"
print $" ($asset) โ ($ipfs_url)"
$rewrites = ($rewrites | append {from: $asset, to: $ipfs_url})
}
if ($rewrites | is-empty) {
return
}
# Rewrite URLs in staged markdown files
for f in $staged {
let path = ([$graph_path $f] | path join)
if not ($path | path exists) { continue }
mut content = (open $path)
for rw in $rewrites {
$content = ($content | str replace --all $rw.from $rw.to)
}
$content | save -f $path
# Re-stage the modified file
cd $graph_path
git add $f
}
print $"IPFS: ($rewrites | length) media files uploaded and rewritten"
}
analizer/ipfs.nu
ฯ 0.0%