Last active
October 22, 2024 15:18
-
-
Save gloriouslyawkwardlife/82f8855832c33468289e0b0afa3d278e to your computer and use it in GitHub Desktop.
Wolfram Language - Create Daily Log Notebook
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ExternalEvaluate[{"Python", | |
"Evaluator" -> <| | |
"PythonRuntime" -> File["/opt/homebrew/bin/python3.12"]|>}, | |
File["/Users/steven/Library/Mobile \ | |
Documents/com~apple~CloudDocs/Scripts/Python/datacollection.py"]]; | |
dbr = DatabaseReference[ | |
URL["mysql://xxx:[email protected]/\ | |
personalinformatics"]]; | |
accessToken = | |
"xxx"; | |
threadsId = "xxx"; | |
nb = CreateNotebook[]; | |
NotebookWrite[nb, { | |
Cell["Daily Log", "Title"], | |
Cell[DateString[Yesterday, "LocaleDateFull"], "Subtitle"], | |
Cell["Apple Health Data", "Section"], | |
Cell["These charts are generated from a daily Apple Health export \ | |
file.", "Text"] | |
}]; | |
DateListPlot[ | |
ExternalEvaluate[dbr, | |
"SELECT endDate,value FROM applehealth WHERE type LIKE \ | |
'%heartrate%' AND sourceName = 'Steven\[CloseCurlyQuote]s \ | |
Apple Watch' AND DATE(endDate) = DATE_SUB(CURDATE(),INTERVAL 1 \ | |
DAY)"], | |
PlotLabel -> | |
"Daily Heart Rate Log \[Bullet] " <> | |
DateString[Yesterday, "LocaleDateLong"], | |
PlotTheme -> "Web", | |
PlotRange -> All, | |
ImageSize -> {700, 300}, | |
AspectRatio -> 3/7, | |
Joined -> False, | |
Filling -> Bottom, | |
LabelingFunction -> (Callout[IntegerPart[#1[[2]]], Automatic] &) | |
] // NotebookWrite[nb, | |
Cell[BoxData[MakeBoxes[#, StandardForm]], "Output"]] &; | |
DateListPlot[ | |
ExternalEvaluate[dbr, | |
"SELECT endDate,value FROM applehealth WHERE type LIKE \ | |
'%stepcount%' AND sourceName = 'Steven\[CloseCurlyQuote]s \ | |
Apple Watch' AND DATE(endDate) = DATE_SUB(CURDATE(),INTERVAL 1 \ | |
DAY)"], | |
PlotLabel -> | |
"Daily Step Log \[Bullet] " <> | |
DateString[Yesterday, "LocaleDateLong"], | |
PlotTheme -> "Web", | |
PlotRange -> All, | |
Joined -> False, | |
Filling -> Bottom, | |
LabelingFunction -> (Callout[IntegerPart[#1[[2]]], Automatic] &), | |
ImageSize -> {700, 300}, | |
AspectRatio -> 3/7 | |
] // NotebookWrite[nb, | |
Cell[BoxData[MakeBoxes[#, StandardForm]], "Output"]] &; | |
DateListPlot[ | |
ExternalEvaluate[dbr, | |
"SELECT DATE(endDate),SUM(value) from applehealth WHERE \ | |
DATE(endDate) >= DATE_SUB(CURDATE(),INTERVAL 30 DAY) AND type LIKE \ | |
'%stepcount%' AND sourceName = 'Steven\[CloseCurlyQuote]s \ | |
Apple Watch' GROUP BY DATE(endDate)"], | |
PlotLabel -> "Daily Step Counts, Last 30 Days", | |
PlotTheme -> "Web", | |
PlotRange -> All, | |
Joined -> False, | |
Filling -> Bottom, | |
LabelingFunction -> (Callout[IntegerPart[#1[[2]]], Automatic] &), | |
ImageSize -> {700, 300}, | |
AspectRatio -> 3/7 | |
] // NotebookWrite[nb, | |
Cell[BoxData[MakeBoxes[#, StandardForm]], "Output"]] &; | |
NotebookWrite[nb, { | |
Cell["Travel & Location Data", "Section"], | |
Cell["These charts are generated from Bouncie and Swarm \ | |
application data.", "Text"] | |
}]; | |
NotebookWrite[nb, Cell["Maps", "Subsection"]]; | |
d = ExternalEvaluate[dbr, | |
"SELECT latitude,longitude,venue,createdAt FROM checkins WHERE \ | |
privacy IS NULL AND DATE(createdAt) = DATE_SUB(CURDATE(),INTERVAL 1 \ | |
DAY)"]; | |
If[ | |
Length[d] > 0, | |
points = | |
Table[GeoPosition[{d[[i, "latitude"]], d[[i, "longitude"]]}], {i, | |
Length[d]}]; | |
labels = Table[d[[i, "venue"]], {i, Length[d]}]; | |
locations = DeleteDuplicates@MapThread[Callout, {points, labels}]; | |
GeoListPlot[ | |
locations, | |
GeoBackground -> "StreetMap", | |
GeoRangePadding -> Scaled[0.5], | |
ImageSize -> {700, 500}, | |
AspectRatio -> 5/7, | |
GeoScaleBar -> {"Imperial", "Metric"}, | |
PlotLabel -> | |
"Daily Checkins \[Bullet] " <> | |
DateString[Yesterday, "LocaleDateLong"] <> | |
"\n(Checkins at private locations not included on map)" | |
] // NotebookWrite[nb, | |
Cell[BoxData[MakeBoxes[#, StandardForm]], "Output"]] &, | |
Notebookwrite[nb, Cell["No checkins to report.", "Text"]] | |
] | |
d = ExternalEvaluate[dbr, | |
"SELECT gps FROM bouncietrips WHERE DATE(startTime) = \ | |
DATE_SUB(CURDATE(),INTERVAL 1 DAY) OR DATE(endTime) = \ | |
DATE_SUB(CURDATE(),INTERVAL 1 DAY)"]; | |
If[ | |
Length[d] > 0, | |
gj = <|"type" -> "FeatureCollection", "features" -> {}|>; | |
Do[ | |
AppendTo[ | |
gj[["features"]], {"type" -> "Feature", "properties" -> <||>, | |
"geometry" -> ImportString[d[[i, "gps"]], "RawJSON"]}] | |
, {i, Length[d]} | |
]; | |
gjout = ExportString[gj, "JSON"]; | |
ImportString[ | |
gjout, | |
"GeoJSON", | |
PlotLabel -> | |
"Bouncie Driving Log\nTrips Start or End on " <> | |
DateString[Yesterday, "LocaleDateLong"], | |
GeoBackground -> "StreetMap", | |
GeoRangePaddding -> Automatic, | |
GeoScaleBar -> {"Imperial", "Metric"}, | |
ImageSize -> {700, 500}, | |
AspectRatio -> 5/7 | |
] // NotebookWrite[nb, | |
Cell[BoxData[MakeBoxes[#, StandardForm]], "Output"]] &, | |
NotebookWrite[nb, Cell["No trips to report.", "Text"]] | |
] | |
NotebookWrite[nb, Cell["Travel Log", "Subsection"]]; | |
log = {}; | |
d = ExternalEvaluate[dbr, | |
"SELECT createdAt,venue,category FROM checkins WHERE privacy IS \ | |
NULL AND DATE(createdAt) = DATE_SUB(CURDATE(),INTERVAL 1 DAY)"]; | |
Do[ | |
AppendTo[ | |
log, <|"startTime" -> d[[i, "createdAt"]], | |
endTime -> d[[i, "createdAt"]], | |
"Event" -> | |
"Checked in at " <> d[[i, "venue"]] <> " (" <> | |
d[[i, "category"]] <> ")"|>] | |
, {i, Length[d]}]; | |
d = ExternalEvaluate[dbr, | |
"SELECT startTime, endTime FROM bouncietrips WHERE DATE(startTime) \ | |
= DATE_SUB(CURDATE(),INTERVAL 1 DAY) OR DATE(endTime) = \ | |
DATE_SUB(CURDATE(),INTERVAL 1 DAY)"]; | |
Do[ | |
AppendTo[ | |
log, | |
<| | |
"startTime" -> d[[i, "startTime"]], | |
"endTime" -> d[[i, "endTime"]], "Event" -> "On the road..."|> | |
], {i, Length[d]}]; | |
log = SortBy[log, #startTime &]; | |
If[ | |
Length[log] > 0, | |
TextGrid[Table[ | |
{ | |
If[ | |
MissingQ[log[[i, "endTime"]]], | |
DateString[log[[i, "startTime"]], "LocaleTimeCompact"], | |
DateString[log[[i, "startTime"]], "LocaleTimeCompact"] <> | |
" - " <> DateString[log[[i, "endTime"]], "LocaleTimeCompact"] | |
], | |
log[[i, "Event"]] | |
} | |
, {i, Length[log]}]] // | |
NotebookWrite[nb, | |
Cell[BoxData[MakeBoxes[#, StandardForm]], "Output"]] &, | |
NotebookWrite[nb, Cell["There was no travel to report.", "Text"]] | |
]; | |
NotebookWrite[nb, | |
Cell["The contents of this page are Copyright © " <> | |
DateString[Now, "Year"] <> | |
" Steven W. Buehler. All Rights Reserved.\n\ | |
https://gloriouslyawkwardlife.com\n\ | |
https://gloriouslyawkwardlife.notion.site\nGenerated Using Wolfram \ | |
Language.", "Text", CellFrame -> True, Alignment -> Center]]; | |
(* Write/Export Notebook Images and file to Cloud & Local *) | |
CloudPublish[ExportForm[nb, "PNG"], | |
DateString[Yesterday, "ISODate"] <> "_dailylog.png", | |
Permissions -> "Public"]; | |
CloudPublish[nb, "DailyLog.nb", | |
Permissions -> {"All" -> "Read", "Owner" -> {All}}]; | |
Export["/Users/steven/Downloads/dailylog.png", nb, "PNG"]; | |
NotebookSave[nb, | |
"/Users/steven/Downloads/" <> DateString[Yesterday, "ISODate"] <> | |
" Daily Log.nb"]; | |
NotebookClose[nb]; | |
(* Threads Post Part 2: Create Media container *) | |
postcontainerId = Import[ | |
HTTPRequest[ | |
URL[ | |
"https://graph.threads.net/v1.0/" <> threadsId <> "/threads"], | |
<| | |
Method -> "POST", | |
"Query" -> { | |
"media_type" -> "IMAGE", | |
"image_url" -> | |
"https://www.wolframcloud.com/obj/xxxx/" <> | |
DateString[Yesterday, "ISODate"] <> "_dailylog.png", | |
"text" -> "#Lifelogging: Daily Personal Charts, " <> | |
DateString[Yesterday, "LocaleDateLong"] <> | |
", generated using the Wolfram Language from \ | |
@wolframresearch. Notebook version at \ | |
https://www.wolframcloud.com/obj/xxxx/DailyLog.nb", | |
"access_token" -> accessToken | |
} | |
|> | |
] | |
, "RawJSON"][["id"]]; | |
(* Threads Post Part 3: Post the container *) | |
post = URLExecute[ | |
HTTPRequest[ | |
URL[ | |
"https://graph.threads.net/v1.0/" <> threadsId <> | |
"/threads_publish"], | |
<| | |
Method -> "POST", | |
"Query" -> { | |
"creation_id" -> postcontainerId, | |
"access_token" -> accessToken | |
} | |
|> | |
] | |
]; | |
(* Update image block on home page *) | |
URLExecute[ | |
HTTPRequest[ | |
"https://api.notion.com/v1/blocks/xxxx", | |
<| | |
Method -> "PATCH", | |
"Headers" -> { | |
"Authorization" -> | |
"Bearer xxxx", | |
"Notion-Version" -> "2022-06-28" | |
}, | |
"ContentType" -> "application/json", | |
"Body" -> ExportString[{ | |
"image" -> { | |
"external" -> { | |
"url" -> | |
"https://www.wolframcloud.com/obj/xxxx/" <> | |
DateString[Yesterday, "ISODate"] <> "_dailylog.png" | |
} | |
} | |
}, "JSON"] | |
|> | |
] | |
]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment