Skip to content

Instantly share code, notes, and snippets.

@Gravifer
Last active February 24, 2021 17:37
Show Gist options
  • Save Gravifer/48dad1b2192741ac718f739eb1a25a30 to your computer and use it in GitHub Desktop.
Save Gravifer/48dad1b2192741ac718f739eb1a25a30 to your computer and use it in GitHub Desktop.
WakaTime API for Mathematica
(* ::Package:: *)
(* ::Title:: *)
(*Mathematica WakaTime Plugin*)
(* ::Author:: *)
(*Author: Gravifer*)
(*Date: 2021-02-21*)
(*Version: 0.0.3*)
BeginPackage["WakaTime`"]
ClearAll[Evaluate[Context[] <> "*"]]
Begin["`Private`"]
ClearAll[Evaluate[Context[] <> "*"]]
GetWakaEXE[]:=If[#[["ExitCode"]]==0,Identity[$wakaEXE=StringReplace[#[["StandardOutput"]],{"\\"->"/","\r"->"","\n"->""}]],Print["wakatime.exe is not found"];$Failed]&@RunProcess[{"where.exe", "wakatime"}]
GetWakaEXE[]
$WakaTimePluginVersion="v0.0.3"
WakaTime::unsaved="The current file is not on the disk, and the heartbeat cannot be sent. (This message only issue once for the current file)";
Once[If[ValueQ[$PrePrint],$WakaTimePreReadBackUp=$PreRead]]
UpdateHeartbeat[]:=(Once[$LastHeartbeat=AbsoluteTime[]];
If[Not[ValueQ[$LastHeartbeat]]&&(AbsoluteTime[]-$LastHeartbeat>0),
Quiet@Unset@Once[$LastHeartbeat=AbsoluteTime[]];Once[$LastHeartbeat=AbsoluteTime[]];True,
False])
GetGitFolder[]:=(If[#[["ExitCode"]]==0,
Set[$gitFolder,Last[FileNameSplit@#[["StandardOutput"]]]],
Unset[$gitFolder]]&@Evaluate[RunProcess[{"git","rev-parse","--show-toplevel"}]];)
GetCurrentProject[]:=($CurrentProject=If[ValueQ[$gitFolder],
StringTemplate["\"`gitFolder`\""][<|"gitFolder"->$gitFolder|>],"\"wolfram-wakatime\""])
GetCurrentFile[]:=If[Not[Enclose[StringReplace[Quiet@Confirm@NotebookFileName[],"\\"->"/"],Null&]===Null],
Set[$CurrentFile,StringReplace[Quiet@NotebookFileName[],"\\"->"/"]],
Unset[$CurrentFile]];
ManageEvaluationNotebookChange[]:=(#;If[Not[$CurrentNotebook===EvaluationNotebook[]],
Quiet@Unset@Once[Message[WakaTime::unsaved]];GetGitFolder[];GetCurrentProject[];GetCurrentFile[];Unset@#];#;)&@
Unevaluated[Once[$CurrentNotebook=Quiet@EvaluationNotebook[]]];
SendHeartbeat[]:=If[ValueQ[$CurrentFile],StartProcess[{$wakaEXE, "--write",
"--plugin" ,
StringTemplate["\"Mathematica-wakatime-gravifer-plugin/`PlugInVersion`\""][<|"PlugInVersion"->$WakaTimePluginVersion|>],
"--entity" ,
StringTemplate["\"`CurrentFile`\""][<|"CurrentFile"->$CurrentFile|>],
"--language",
"\"Wolfram\"",
"--project",
StringTemplate["\"`CurrentProject`\""][<|"CurrentProject"->$CurrentProject|>]}],
Once[Message[WakaTime::unsaved]]]
$PreRead=(ManageEvaluationNotebookChange[];If[UpdateHeartbeat[],SendHeartbeat[]];
If[ValueQ[$WakaTimePreReadBackUp],$WakaTimePreReadBackUp[#],#])&;
End[]
EndPackage[]

WakaTime API for Mathematica

  1. Make sure you have installed the official WakaTime CLI;
  2. To check the installation has exported to the PATH, in MMA execute
StringReplace[RunProcess[{"where.exe", "wakatime"}][["StandardOutput"]], {"\\" -> "/", "\r" -> "", "\n" -> ""}]

The output should be a valid path where the wakatime binary can be found. 3. Modify the $PrePrint variable in your personal init.m file

$PreRead = (StartProcess[
  {"wakatime", "--write",
    "--plugin", StringTemplate["\"Mathematica-wakatime-gravifer-plugin/`PlugInVersion`\""][<|"PlugInVersion" -> "v0.0.1"|>],
    "--entity", StringTemplate["\"`CurrentFile`\""][<|"CurrentFile" -> StringReplace[NotebookFileName[], "\\" -> "/"]|>],
    "--language", "\"Wolfram\""
  }]; #) &;

This should give you a basic logging feature. I am developing this into a more self-contained paclet; feel free to contact me on this subject at any time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment