Timing.app (https://timingapp.com) is a powerful time tracking application for the Mac. During the day, it tracks open apps, calendar entries, and other events, and at the end of the day, you can assign the time spent to your projects in order to bill the customers and to know how you have spent your time.
With this small script, you can now also automatically sync/import phone calls from the FRITZ!Box Call List to Timing.app.
Tested with FRITZ!Box 6490 Cable (FritzOS 06.87) and Timing.app 2018.4.
Besides a scriptable version of Timing.app (read: Timing Expert license), the script needs Python 3.7 and the modules fritzconnect and osascript.
Using MacPorts, getting the requirements basically boils down to (YMMV):
sudo port install python37
sudo port select --set python3 python37
sudo port select --set python python37
sudo port select --set pip pip37
sudo pip install fritzconnect osascript
Next, clone the repository:
In Timing.app create a project called Telefon. All phone calls will be added as tasks to this project. (This is currently not configurable, you could add an option and send me a pull request or hard-code a different project in the script).
The idea is that at the end of the day you can check your phone calls in that target project and reassign them to the actual projects they belong to, or delete any phone-related tasks which you don't want to include.
Copy the configuration file example.phonetotiming.ini
to your home directory and
rename it to .phonetotiming.ini
Edit the contents:
[main]
password = <your Fritz!Box password here>
firstrun = true
debug = false
For the password
set the correct Fritz!Box password. This is all you need to do.
The existence of the key firstrun
with any value indicates that the script has not run before. On the first run, the script will remove this entry and instead add a lastprocessed
entry which contains the Id of the most recent entry in the call list.
The lastprocessed
entry will be updated by the script on every run to keep track which calls have been written to
Timing.app already.
After you have copied and edited the configuration file, run the script manually for the first time. (No worries! It will not write anything to Timing.app, yet, because the firstrun
key exists!)
$ ./phonetotiming.py
\o/ - everything seems to work. The latest call on your call list has the Id 1568.
If you see this output, everything is working. The script has read the call list and updated the configuration file with the ID shown.
Every subsequent phone call will be sent to Timing.app in the next run of the script.
To make the script run regularly (default: every 10 minutes), edit the file net.winklerweb.phonetotiming.plist
and in line 9 set the correct path to the phonetotiming.py script.
$ cp net.winklerweb.phonetotiming.plist ~/Library/LaunchAgents/
$ cd ~/Library/LaunchAgents
$ launchctl load net.winklerweb.phonetotiming.plist
$ launchctl start net.winklerweb.phonetotiming.plist
Note that both running manually and via launchd for the first time will show a dialog about the script remote-controlling Timing.app. You need to allow this once for each invocation method.
The net.winklerweb.phonetotiming.plist
file also contains paths to files to which output and error streams are written.
In the configuration file, you can set debug = true
to get some output. This can be used to check whether the script is executed on a regular basis.