Skip to content

Instantly share code, notes, and snippets.

@MrGung
Created April 16, 2022 08:33
Show Gist options
  • Save MrGung/3a43e3f7e34360195505e72f8e14962a to your computer and use it in GitHub Desktop.
Save MrGung/3a43e3f7e34360195505e72f8e14962a to your computer and use it in GitHub Desktop.
download remote #logseq media and replace links to point to local assets. converting from #logseq web-app to desktop-app. written in #clojure, executable with #babashka.
(ns logseq.convert-remote-images-to-local
(:require
[babashka.fs :as fs]
[babashka.curl :as curl]
[clojure.java.io :as io]
[clojure.string :as str]))
;; download remote #logseq media and replace links to point to local assets.
;; converting from #logseq web-app to desktop-app.
;; written in #clojure, executable with #babashka.
;; call with
;; bb convert_remote_images_to_local.clj "c:\\Users\\Steffen\\Documents\\Steffen\\DEV\\clojure\\logseq"
(def logseq-root (first *command-line-args*))
#_(def logseq-root "c:\\Users\\Steffen\\Documents\\Steffen\\DEV\\clojure\\logseq")
;; restricting to logseq-content use: #"!\[([^\]]*)\]\((https://cdn\.logseq\.com[^\)]*)\)"
;;
(def media-pattern #"!\[([^\]]*)\]\((http(?:s?)://[^\)]*)\)")
(def glob-pattern "{pages,journal}/**.md")
(defn file-content-matching? [pattern content]
(boolean (re-find pattern content)))
(defn file-matches? [fil]
(->> fil
fs/file
slurp
(file-content-matching? media-pattern)))
(defn copy-uri-to-file [uri file]
(with-open [in (io/input-stream uri)
out (io/output-stream file)]
(io/copy in out)))
(defn replace-media-links-in-file [pattern replacer fil]
(let [content (slurp fil)
new-content (str/replace content pattern replacer)]
(spit fil new-content)
fil))
(defn create-media-url-with-local-file-replacer [logseq-root]
(fn [match]
(let [assets-dir "assets"
image-name (nth match 1)
target-image-name (let [image-filename (fs/file-name image-name)
uuid (.toString (java.util.UUID/randomUUID))
file-extension (fs/extension image-name)]
(format "%s__%s.%s" image-filename uuid file-extension))
image-url (nth match 2)
target-filename (fs/file logseq-root assets-dir target-image-name)]
(assert (not (fs/exists? target-filename)))
(copy-uri-to-file image-url target-filename)
(format "![%s](../%s/%s)" image-name assets-dir target-image-name))))
(def files (fs/glob logseq-root glob-pattern {:recursive true}))
(def f-files (filter file-matches? files))
(let [replacer (create-media-url-with-local-file-replacer logseq-root)
fs-files (map fs/file f-files)]
(run! (fn [fil]
(println "processing" (fs/file-name fil))
(replace-media-links-in-file media-pattern replacer fil))
fs-files)
(println "done"))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment