diff --git a/deps/common/src/logseq/common/util/date_time.cljs b/deps/common/src/logseq/common/util/date_time.cljs index 3b6b246095..96f3df9d85 100644 --- a/deps/common/src/logseq/common/util/date_time.cljs +++ b/deps/common/src/logseq/common/util/date_time.cljs @@ -79,3 +79,12 @@ [date] (parse-long (string/replace (ymd date) "/" ""))) + +(defn journal-day->ms + "Convert :block/journal-day int to ms timestamp in current timezone" + [journal-day] + (let [journal-day' (str journal-day) + year (js/parseInt (subs journal-day' 0 4)) + month (dec (js/parseInt (subs journal-day' 4 6))) + day (js/parseInt (subs journal-day' 6 8))] + (.getTime (new js/Date year month day)))) diff --git a/deps/graph-parser/src/logseq/graph_parser/exporter.cljs b/deps/graph-parser/src/logseq/graph_parser/exporter.cljs index 7925cc9615..92265169ec 100644 --- a/deps/graph-parser/src/logseq/graph_parser/exporter.cljs +++ b/deps/graph-parser/src/logseq/graph_parser/exporter.cljs @@ -797,13 +797,18 @@ (assoc :block/parent {:block/uuid (get-page-uuid page-names-to-uuids (:block/name (:block/parent block)))}))) (defn- build-block-tx - [db block* pre-blocks page-names-to-uuids {:keys [import-state] :as options}] + [db block* pre-blocks page-names-to-uuids {:keys [import-state journal-created-ats] :as options}] ;; (prn ::block-in block*) (let [;; needs to come before update-block-refs to detect new property schemas {:keys [block properties-tx]} (handle-block-properties block* db page-names-to-uuids (:block/refs block*) options) {block-after-built-in-props :block deadline-properties-tx :properties-tx} (update-block-deadline block db options) - block' (-> block-after-built-in-props + ;; :block/page should be [:block/page NAME] + journal-page-created-at (some-> (:block/page block*) second journal-created-ats) + prepared-block (cond-> block-after-built-in-props + journal-page-created-at + (assoc :block/created-at journal-page-created-at)) + block' (-> prepared-block (fix-pre-block-references pre-blocks page-names-to-uuids) (fix-block-name-lookup-ref page-names-to-uuids) (update-block-refs page-names-to-uuids options) @@ -826,13 +831,15 @@ aliases)))) (defn- build-new-page-or-class - [m db user-options page-names-to-uuids all-idents] + [m db page-names-to-uuids all-idents {:keys [user-options journal-created-ats]}] (-> (cond-> m ;; Fix pages missing :block/title. Shouldn't happen (not (:block/title m)) (assoc :block/title (:block/name m)) (seq (:block/alias m)) - (update-page-alias page-names-to-uuids)) + (update-page-alias page-names-to-uuids) + (journal-created-ats (:block/name m)) + (assoc :block/created-at (journal-created-ats (:block/name m)))) add-missing-timestamps ;; TODO: org-mode content needs to be handled (assoc :block/format :markdown) @@ -943,7 +950,7 @@ (not (some-> (get @(:all-idents import-state) (keyword (:block/title m))) db-malli-schema/class?))) (build-new-page-or-class (dissoc m ::original-name) - @conn user-options page-names-to-uuids (:all-idents import-state))))) + @conn page-names-to-uuids (:all-idents import-state) options)))) (map :block all-pages-m))] {:pages-tx pages-tx :page-properties-tx (mapcat :properties-tx all-pages-m) @@ -1154,6 +1161,14 @@ :else (notify-user {:msg (str "Skipped file since its format is not supported: " file)})))) +(defn- build-journal-created-ats + "Calculate created-at timestamps for journals" + [pages] + (->> pages + (map #(when-let [journal-day (:block/journal-day %)] + [(:block/name %) (date-time-util/journal-day->ms journal-day)])) + (into {}))) + (defn add-file-to-db-graph "Parse file and save parsed data to the given db graph. Options available: @@ -1171,7 +1186,8 @@ :as *options}] (let [options (assoc *options :notify-user notify-user :log-fn log-fn) {:keys [pages blocks]} (extract-pages-and-blocks @conn file content options) - tx-options (build-tx-options options) + tx-options (merge (build-tx-options options) + {:journal-created-ats (build-journal-created-ats pages)}) old-properties (keys @(get-in options [:import-state :property-schemas])) ;; Build page and block txs {:keys [pages-tx page-properties-tx page-names-to-uuids existing-pages]} (build-pages-tx conn pages blocks tx-options) diff --git a/deps/graph-parser/test/logseq/graph_parser/exporter_test.cljs b/deps/graph-parser/test/logseq/graph_parser/exporter_test.cljs index aba8861d73..99427839b9 100644 --- a/deps/graph-parser/test/logseq/graph_parser/exporter_test.cljs +++ b/deps/graph-parser/test/logseq/graph_parser/exporter_test.cljs @@ -18,7 +18,8 @@ [logseq.db :as ldb] [logseq.outliner.db-pipeline :as db-pipeline] [logseq.db.test.helper :as db-test] - [logseq.db.frontend.rules :as rules])) + [logseq.db.frontend.rules :as rules] + [logseq.common.util.date-time :as date-time-util])) ;; Helpers ;; ======= @@ -359,6 +360,14 @@ (rest (expand-children (d/entity @conn (:db/id (find-page-by-name @conn "n2"))) nil))) "First namespace tests duplicate child page name and built-in page name"))) + (testing "journal timestamps" + (is (= (date-time-util/journal-day->ms 20240207) + (:block/created-at (find-page-by-name @conn "Feb 7th, 2024"))) + "journal pages are created on their journal day") + (is (= (date-time-util/journal-day->ms 20240207) + (:block/created-at (find-block-by-content @conn #"Inception"))) + "journal blocks are created on their page's journal day")) + (testing "db attributes" (is (= true (:block/collapsed? (find-block-by-content @conn "collapsed block")))