This is also a pretty simple implementation. So while it’s output is opinionated, it should also be pretty easy to adapt this script to different use cases.
#!/usr/bin/env python3
import os
import json
from datetime import datetime
from zoneinfo import ZoneInfo
# Read in all JSON files in the directory
#
rawDayOneData = {}
for file in os . listdir ( " . " ):
if file . endswith ( " .json " ):
with open ( file ) as jsonData :
rawDayOneData [ file . replace ( " .json " , "" )] = json . load ( jsonData )
# Create master document list
#
journalData = {}
for journalName , rawJournalData in rawDayOneData . items ():
for entry in rawJournalData [ " entries " ]:
entryDateTimeObject = datetime . fromisoformat ( entry [ " creationDate " ])
entryDate = entryDateTimeObject . astimezone ( ZoneInfo ( entry [ " timeZone " ])). strftime ( " %Y-%m- %d " )
entryTime = entryDateTimeObject . astimezone ( ZoneInfo ( entry [ " timeZone " ])). strftime ( " %H:%M " )
entryDateTime = entryDateTimeObject . astimezone ( ZoneInfo ( entry [ " timeZone " ])). strftime ( " %Y-%m- %d T%H:%M:%S " )
entryUuid = entry [ " uuid " ]. lower ()
entryIndex = entryDateTime + " | " + entryUuid
entryTags = " # " + journalName . replace ( " " , "" )
if " tags " in entry :
for tag in entry [ " tags " ]:
entryTags = entryTags + " # " + tag . replace ( " " , "" )
if ( " #Art " in entryTags ) and ( " #Photography " in entryTags ):
entryHeader = " ## " + entryTime + " | Photography "
else :
entryHeader = " ## " + entryTime + " | " + journalName
entryLocation = ""
if " location " in entry :
entryLocation = " [ " + entry [ " location " ][ " placeName " ] + " ](geo: " + str ( round ( entry [ " location " ][ " latitude " ], 4 )) + " , " + str ( round ( entry [ " location " ][ " longitude " ], 4 )) + " ) "
entryWeather = ""
if " weather " in entry :
entryWeather = str ( int ( round ( entry [ " weather " ][ " temperatureCelsius " ], 0 ))) + " °C "
if " conditionsDescription " in entry [ " weather " ]:
entryWeather = entryWeather + " • " + entry [ " weather " ][ " conditionsDescription " ]
elif " weatherCode " in entry [ " weather " ]:
entryWeather = entryWeather + " • " + entry [ " weather " ][ " weatherCode " ]
entryMedia = {}
if " audios " in entry :
for audioFile in entry [ " audios " ]:
entryMedia [ " ![](dayone-moment:/audio/ " + audioFile [ " identifier " ] + " ) " ] = " ![[ " + audioFile [ " md5 " ] + audioFile [ " format " ] + " ]] "
if " pdfs " in entry :
for pdfFile in entry [ " pdfs " ]:
entryMedia [ " ![](dayone-moment:/pdfAttachment/ " + pdfFile [ " identifier " ] + " ) " ] = " ![[ " + pdfFile [ " md5 " ] + " .pdf " + " ]] "
if " photos " in entry :
for imageFile in entry [ " photos " ]:
entryMedia [ " ![](dayone-moment:// " + imageFile [ " identifier " ] + " ) " ] = " ![[ " + imageFile [ " md5 " ] + " . " + imageFile [ " type " ] + " ]] "
if " videos " in entry :
for videoFile in entry [ " videos " ]:
entryMedia [ " ![](dayone-moment:/video/ " + videoFile [ " identifier " ] + " ) " ] = " ![[ " + videoFile [ " md5 " ] + " . " + videoFile [ " type " ] + " ]] "
entryText = entry [ " text " ]
for oldMediaLink , newMediaLink in entryMedia . items ():
entryText = entryText . replace ( oldMediaLink , newMediaLink )
entryText = entryText . replace ( " \n\n\n " , " \n\n " )
entryText = entryText . replace ( " ![[ " , " \n\n ![[ " )
entryText = entryText . replace ( " ]] \n\n ![[ " , " ]] \n ![[ " )
entryText = entryText . replace ( " . \n ![[ " , " . \n\n ![[ " )
entryText = entryText . replace ( " ! \n ![[ " , " ! \n\n ![[ " )
entryText = entryText . replace ( " ? \n ![[ " , " ? \n\n ![[ " )
entryText = entryText . replace ( " ) \n ![[ " , " ) \n\n ![[ " )
entryText = entryText . replace ( " \\ & " , " & " )
entryText = entryText . replace ( " \\ ~ " , " ~ " )
entryText = entryText . replace ( " \\ - " , " - " )
entryText = entryText . replace ( " \\ _ " , " _ " )
entryText = entryText . replace ( " \\ + " , " + " )
entryText = entryText . replace ( " \\ . " , " . " )
entryText = entryText . replace ( " \\ ! " , " ! " )
entryText = entryText . replace ( " \\ ( " , " ( " )
entryText = entryText . replace ( " \\ ) " , " ) " )
entryText = entryText . replace ( " \\ { " , " { " )
entryText = entryText . replace ( " \\ } " , " } " )
entryText = entryText . replace ( " \\ [ \\ ] " , " [] " )
entryText = entryText . replace ( " \\\\ " , " \\ " )
entryText = entryText . replace ( " [ * " , " [* " )
entryText = entryText . replace ( " * ] " , " *] " )
entryText = entryText . replace ( " # " , " ⌗ " )
entryText = entryText . replace ( " $ " , " $ " )
entryText = entryText . replace ( " --- " , " — " )
entryText = entryText . replace ( " -- " , " – " )
entryText = entryText . replace ( " ... " , " … " )
entryText = entryText . strip ()
if entryDate not in journalData :
journalData [ entryDate ] = {}
journalData [ entryDate ][ entryIndex ] = {}
journalData [ entryDate ][ entryIndex ][ " header " ] = entryHeader
journalData [ entryDate ][ entryIndex ][ " uuid " ] = entryUuid
journalData [ entryDate ][ entryIndex ][ " datetime " ] = entryDateTime
journalData [ entryDate ][ entryIndex ][ " tags " ] = entryTags
if len ( entryLocation ) > 0 :
journalData [ entryDate ][ entryIndex ][ " location " ] = entryLocation
if len ( entryWeather ) > 0 :
journalData [ entryDate ][ entryIndex ][ " weather " ] = entryWeather
journalData [ entryDate ][ entryIndex ][ " text " ] = entryText
journalData = dict ( sorted ( journalData . items ()))
for journalDate , journalEntries in journalData . items ():
journalData [ journalDate ] = dict ( sorted ( journalEntries . items ()))
for journalDate , journalEntries in journalData . items ():
journalDateTime = datetime . strptime ( journalDate , " %Y-%m- %d " )
journalDayNumber = journalDateTime . strftime ( " %-d " )
journalDaySuffix = " th "
if ( journalDayNumber == " 1 " ) or ( journalDayNumber == " 21 " ) or ( journalDayNumber == " 31 " ):
journalDaySuffix = " st "
elif ( journalDayNumber == " 2 " ) or ( journalDayNumber == " 22 " ):
journalDaySuffix = " nd "
elif ( journalDayNumber == " 3 " ) or ( journalDayNumber == " 23 " ):
journalDaySuffix = " rd "
journalDayName = journalDateTime . strftime ( " %A " )
journalHumanDate = journalDateTime . strftime ( " %B " ) + " " + journalDayNumber + journalDaySuffix + " " + journalDateTime . strftime ( " %Y " )
journalAmericanDate = journalDateTime . strftime ( " %-m/ %-d /%Y " )
journalFileName = journalDate + " " + journalDayName + " .md "
with open ( journalFileName , " w " ) as journalFile :
print ( " --- " , file = journalFile )
print ( " title: Journal for " + journalDayName + " , " + journalHumanDate , file = journalFile )
print ( " date: " + journalDate , file = journalFile )
print ( " tags: " , file = journalFile )
print ( " - Journal " , file = journalFile )
print ( " aliases: " , file = journalFile )
print ( " - Journal for " + journalDayName + " , " + journalHumanDate , file = journalFile )
print ( " - " + journalDayName + " , " + journalHumanDate , file = journalFile )
print ( " - " + journalHumanDate , file = journalFile )
print ( " - " + journalDate , file = journalFile )
print ( " - " + journalAmericanDate , file = journalFile )
print ( " locations: " , file = journalFile )
print ( " --- " , file = journalFile )
for entryId , entry in journalEntries . items ():
print ( entry [ " header " ], file = journalFile )
print ( " [dayOneId:: " + entry [ " uuid " ] + " ] " , file = journalFile )
print ( " [datetime:: " + entry [ " datetime " ] + " ] " , file = journalFile )
print ( " [tags:: " + entry [ " tags " ] + " ] " , file = journalFile )
if " location " in entry :
print ( " [location:: " + entry [ " location " ] + " ] " , file = journalFile )
if " weather " in entry :
print ( " [weather:: " + entry [ " weather " ] + " ] " , file = journalFile )
print ( "" , file = journalFile )
print ( entry [ " text " ], file = journalFile )
print ( "" , file = journalFile )