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.

Revisions

  1. MrGung created this gist Apr 16, 2022.
    72 changes: 72 additions & 0 deletions convert_remote_images_to_local.clj
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,72 @@
    (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"))