Skip to content

Instantly share code, notes, and snippets.

@SpotlightKid
Forked from yloiseau/watson-notify
Last active September 22, 2017 07:47
Show Gist options
  • Save SpotlightKid/3519751a3dfa4fb80fc9 to your computer and use it in GitHub Desktop.
Save SpotlightKid/3519751a3dfa4fb80fc9 to your computer and use it in GitHub Desktop.
Watson desktop notifier (Python)

Requirements

Indirect dependencies in parentheses:

  • python-notify2 (python-dbus, python-gi)
  • python-arrow (python-dateutil)
  • Watson (click)

Installation

mkdir -p "$HOME/bin"
install watson-notify "$HOME/bin"
mkdir -p "$HOME/.local/share/icons"
install logo-watson-notext.svg "$HOME/.local/share/icons"
crontab -e


*/15 * * * 1-5 watson-notify -i "~/.local/share/icons"
Display the source blob
Display the rendered blob
Raw
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xml:space="preserve"
enable-background="new 0 0 539.295 184.252"
viewBox="0 0 174.68601 175"
height="175"
width="174.686"
y="0px"
x="0px"
id="Calque_1"
version="1.1"><metadata
id="metadata408"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs406" /><g
transform="translate(-3.809,-4.692)"
id="g240"><path
style="clip-rule:evenodd;fill:#2e3e50;fill-rule:evenodd"
id="path242"
d="M 47.596,22.36 C 58.713,15.546 71.688,10.587 88.883,9.848 c 1.564,0 3.127,0 4.691,0 17.121,0.71 29.93,5.729 41.133,12.355 -1.373,2.005 -3.422,3.89 -5.318,5.787 -1.936,1.937 -3.904,3.936 -5.941,5.63 -8.086,-4.375 -17.143,-7.778 -29.09,-8.29 -1.93,-0.261 -4.953,-0.261 -6.883,0 C 75.6,25.811 66.676,29.241 58.543,33.463 54.985,29.672 51.153,26.153 47.596,22.36 Z" /><path
style="clip-rule:evenodd;fill:#2e3e50;fill-rule:evenodd"
id="path244"
d="m 91.073,129.023 c 0.053,0 0.105,0 0.156,0 4.834,4.966 9.736,9.867 14.703,14.702 0.299,0.43 0.662,0.795 1.094,1.094 6.867,7.208 14.219,13.933 20.957,21.27 -9.277,4.384 -19.453,7.866 -32.531,8.446 -0.525,0.099 -1.451,-0.201 -1.719,0.157 -1.254,0 -2.504,0 -3.754,0 -0.27,-0.358 -1.195,-0.058 -1.721,-0.157 -13.588,-0.643 -24.188,-4.278 -33.627,-9.07 4.654,-4.888 9.58,-9.502 14.234,-14.389 3.768,-3.583 7.346,-7.354 11.104,-10.948 3.768,-3.637 7.469,-7.338 11.104,-11.105 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path246"
d="m 47.596,22.36 c 3.557,3.793 7.389,7.312 10.947,11.104 -3.636,-3.61 -7.834,-7.493 -10.947,-11.104 z" /><path
style="clip-rule:evenodd;fill:#dae9e7;fill-rule:evenodd"
id="path248"
d="m 123.448,33.622 c 2.037,-1.695 4.006,-3.694 5.941,-5.63 1.896,-1.897 3.945,-3.782 5.318,-5.787 0.672,0.375 -0.619,1.032 -0.939,1.408 -0.373,0.616 -1.031,0.949 -1.406,1.564 -1.082,0.846 -1.889,1.968 -2.973,2.815 -1.914,1.838 -3.898,4.441 -5.941,5.63 z" /><path
style="clip-rule:evenodd;fill:#dae9e7;fill-rule:evenodd"
id="path250"
d="m 147.688,32.214 c 1.439,1.324 2.869,2.657 4.066,4.222 -1.339,-1.423 -2.75,-2.776 -4.066,-4.222 z" /><path
style="clip-rule:evenodd;fill:#a4cdc8;fill-rule:evenodd"
id="path252"
d="m 136.743,28.303 c 0.844,-0.875 1.967,-2.304 2.812,-2.658 -1.027,0.794 -1.785,1.864 -2.812,2.658 z" /><path
style="clip-rule:evenodd;fill:#dae9e7;fill-rule:evenodd"
id="path254"
d="m 133.301,31.745 c 1.08,-1.212 2.227,-2.36 3.441,-3.441 -1.083,1.212 -2.232,2.359 -3.441,3.441 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path256"
d="m 128.608,36.749 c 0.406,-0.898 1.889,-2.073 2.814,-2.972 -0.845,1.082 -1.966,1.89 -2.814,2.972 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path258"
d="m 136.897,43.474 c 0.953,0.821 1.838,1.708 2.658,2.659 -0.951,-0.822 -1.838,-1.707 -2.658,-2.659 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path260"
d="m 124.385,125.426 c 4.602,4.471 9.137,9.006 13.607,13.606 0.766,-0.173 0.926,-0.949 1.562,-1.251 -0.477,0.513 -0.826,1.154 -1.562,1.407 -4.445,-4.678 -9.161,-9.084 -13.607,-13.762 z" /><path
style="clip-rule:evenodd;fill:#a4cdc8;fill-rule:evenodd"
id="path262"
d="m 95.297,96.337 c 9.029,8.901 17.998,17.867 26.898,26.899 -9.03,-8.901 -17.997,-17.868 -26.898,-26.899 z" /><path
style="clip-rule:evenodd;fill:#dae9e7;fill-rule:evenodd"
id="path264"
d="m 91.073,92.269 c 0.846,0.354 1.971,1.785 2.816,2.66 -1.029,-0.795 -1.785,-1.865 -2.816,-2.66 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path266"
d="m 70.897,112.445 c 6.088,-6.216 12.24,-12.368 18.457,-18.455 -6.088,6.217 -12.238,12.369 -18.457,18.455 z" /><path
style="clip-rule:evenodd;fill:#36b097;fill-rule:evenodd"
id="path268"
d="m 66.362,116.824 c 1.604,-1.368 2.932,-3.012 4.535,-4.379 6.219,-6.085 12.369,-12.238 18.457,-18.455 0.549,-0.598 1.246,-1.046 1.719,-1.721 1.031,0.795 1.787,1.865 2.816,2.66 0.402,0.535 0.869,1.003 1.408,1.408 8.9,9.031 17.867,17.998 26.898,26.899 0.664,0.797 1.514,1.407 2.189,2.19 4.445,4.679 9.162,9.084 13.607,13.763 0.736,-0.253 1.086,-0.894 1.562,-1.407 9.635,-10.645 17.053,-23.507 18.143,-42.696 0.262,-1.722 0.262,-4.535 0,-6.256 -1.09,-19.19 -8.508,-32.052 -18.143,-42.696 -0.82,-0.951 -1.705,-1.838 -2.658,-2.659 -2.551,-2.453 -5.381,-4.628 -8.289,-6.725 0.848,-1.083 1.969,-1.89 2.814,-2.972 0.533,-0.771 1.346,-1.262 1.879,-2.033 1.209,-1.082 2.357,-2.229 3.441,-3.441 1.027,-0.794 1.785,-1.864 2.812,-2.658 0.053,0 0.105,0 0.156,0 2.748,2.102 5.373,4.323 7.977,6.569 1.316,1.446 2.727,2.799 4.066,4.222 11.561,13.045 20.207,29.006 21.582,52.237 0.104,0.94 -0.205,2.292 0.158,2.971 0,0.209 0,0.417 0,0.625 -0.363,0.681 -0.055,2.032 -0.158,2.972 -1.375,23.231 -10.02,39.191 -21.582,52.236 -1.34,1.423 -2.75,2.776 -4.066,4.223 -3.846,3.349 -7.771,6.617 -12.199,9.384 -3.322,-2.725 -6.033,-6.06 -9.227,-8.915 -0.051,0 -0.104,0 -0.156,0 -0.664,-0.795 -1.395,-1.525 -2.189,-2.19 0,-0.052 0,-0.104 0,-0.157 -2.697,-2.828 -5.461,-5.591 -8.289,-8.289 -1.551,-1.315 -2.828,-2.907 -4.381,-4.223 -6.605,-6.737 -13.279,-13.41 -20.018,-20.018 -2.26,1.475 -5.826,5.513 -8.131,7.819 -2.816,2.814 -5.598,5.367 -7.979,7.977 -0.168,0.038 -0.105,0.311 -0.311,0.312 -5.645,5.514 -11.223,11.092 -16.736,16.735 -2.619,2.489 -5.172,5.044 -7.664,7.663 -0.377,0.248 -0.689,0.56 -0.938,0.939 -1.002,0.666 -1.525,1.811 -2.658,2.346 -4.352,-2.895 -8.436,-6.058 -12.199,-9.54 -0.979,-1.108 -2.018,-2.151 -3.127,-3.128 C 19.602,135.275 10.579,119.277 9.122,95.71 9.02,94.978 9.327,93.837 8.966,93.364 c 0,-0.938 0,-1.876 0,-2.814 1.053,-24.804 10.225,-41.49 22.521,-55.052 1.109,-0.978 2.148,-2.021 3.127,-3.128 2.57,-2.38 5.307,-4.601 8.133,-6.725 1.135,0.898 1.992,2.073 3.127,2.971 0.744,0.979 1.76,1.681 2.504,2.659 1.395,1.524 2.855,2.984 4.381,4.379 0.098,0.461 1.008,0.632 0.625,1.094 -3.195,1.967 -5.951,4.372 -8.604,6.881 -0.848,0.717 -1.629,1.5 -2.346,2.346 -9.674,10.502 -17.047,23.304 -18.299,42.228 -0.262,2.139 -0.262,5.369 0,7.507 1.252,18.924 8.625,31.726 18.299,42.228 0.322,0.563 0.928,0.844 1.252,1.407 7.779,-7.285 15.156,-14.975 22.676,-22.521 z" /><path
style="clip-rule:evenodd;fill:#dae9e7;fill-rule:evenodd"
id="path270"
d="m 42.434,137.938 c 0.562,0.322 0.844,0.928 1.406,1.25 7.6,-7.363 14.924,-15.001 22.521,-22.364 -7.52,7.545 -14.896,15.236 -22.676,22.521 -0.323,-0.563 -0.929,-0.844 -1.251,-1.407 z" /><path
style="clip-rule:evenodd;fill:#a4cdc8;fill-rule:evenodd"
id="path272"
d="m 42.434,45.976 c 0.717,-0.846 1.498,-1.629 2.346,-2.346 -0.717,0.848 -1.498,1.63 -2.346,2.346 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path274"
d="m 48.377,31.275 c 1.525,1.395 2.984,2.854 4.381,4.379 C 51.233,34.26 49.772,32.8 48.377,31.275 Z" /><path
style="clip-rule:evenodd;fill:#dae9e7;fill-rule:evenodd"
id="path276"
d="m 42.747,25.645 c 0.949,0.458 2.176,1.992 3.127,2.971 -1.135,-0.898 -1.993,-2.073 -3.127,-2.971 z" /><path
style="clip-rule:evenodd;fill:#a4cdc8;fill-rule:evenodd"
id="path278"
d="m 31.487,35.498 c 0.977,-1.108 2.02,-2.15 3.127,-3.128 -0.979,1.107 -2.018,2.15 -3.127,3.128 z" /><path
style="clip-rule:evenodd;fill:#dae9e7;fill-rule:evenodd"
id="path280"
d="m 147.688,151.701 c 1.316,-1.447 2.727,-2.8 4.066,-4.223 -1.197,1.564 -2.627,2.898 -4.066,4.223 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path282"
d="m 126.262,152.17 c 3.193,2.854 5.904,6.19 9.227,8.915 -3.114,-2.265 -6.199,-5.96 -9.227,-8.915 z" /><path
style="clip-rule:evenodd;fill:#dae9e7;fill-rule:evenodd"
id="path284"
d="m 123.917,149.98 c 0.795,0.665 1.525,1.395 2.189,2.19 -0.795,-0.665 -1.525,-1.395 -2.189,-2.19 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path286"
d="m 115.627,141.534 c 2.828,2.698 5.592,5.461 8.289,8.289 -2.828,-2.697 -5.591,-5.46 -8.289,-8.289 z" /><path
style="clip-rule:evenodd;fill:#dae9e7;fill-rule:evenodd"
id="path288"
d="m 91.229,117.294 c 6.738,6.607 13.412,13.28 20.018,20.018 -6.737,-6.608 -13.411,-13.281 -20.018,-20.018 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path290"
d="m 75.12,133.09 c 2.381,-2.61 5.162,-5.162 7.979,-7.977 2.305,-2.307 5.871,-6.344 8.131,-7.819 -5.616,5.018 -10.622,10.647 -16.11,15.796 z" /><path
style="clip-rule:evenodd;fill:#a4cdc8;fill-rule:evenodd"
id="path292"
d="m 58.073,150.136 c 5.514,-5.643 11.092,-11.221 16.736,-16.735 -5.514,5.645 -11.092,11.223 -16.736,16.735 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path294"
d="m 50.409,157.799 c 2.492,-2.619 5.045,-5.174 7.664,-7.663 -2.489,2.62 -5.045,5.175 -7.664,7.663 z" /><path
style="clip-rule:evenodd;fill:#dae9e7;fill-rule:evenodd"
id="path296"
d="m 46.813,161.084 c 1.133,-0.536 1.656,-1.68 2.658,-2.346 -0.812,0.752 -1.717,2.243 -2.658,2.346 z" /><path
style="clip-rule:evenodd;fill:#a4cdc8;fill-rule:evenodd"
id="path298"
d="m 31.487,148.416 c 1.109,0.978 2.148,2.02 3.127,3.128 -1.108,-0.978 -2.151,-2.02 -3.127,-3.128 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path300"
d="m 107.026,144.819 c 5.361,5.134 10.615,10.615 15.953,15.952 1.744,1.745 3.76,3.271 5.004,5.317 -6.738,-7.337 -14.09,-14.062 -20.957,-21.269 z" /><path
style="clip-rule:evenodd;fill:#a4cdc8;fill-rule:evenodd"
id="path302"
d="m 91.229,129.023 c 4.967,4.835 9.867,9.735 14.703,14.702 -4.967,-4.835 -9.869,-9.736 -14.703,-14.702 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path304"
d="m 79.969,140.126 c 3.635,-3.766 7.336,-7.468 11.104,-11.104 -3.635,3.768 -7.336,7.469 -11.104,11.104 z" /><path
style="clip-rule:evenodd;fill:#dae9e7;fill-rule:evenodd"
id="path306"
d="m 54.631,165.464 c 4.211,-4.706 9.502,-9.684 14.234,-14.389 -4.654,4.887 -9.579,9.501 -14.234,14.389 z" /><path
style="clip-rule:evenodd;fill:#a4cdc8;fill-rule:evenodd"
id="path308"
d="m 8.965,90.55 c 0,0.938 0,1.877 0,2.814 0,0.209 0,0.417 0,0.626 -0.053,0 -0.104,0 -0.156,0 0,-1.355 0,-2.711 0,-4.066 0.233,0.029 0.143,0.378 0.156,0.626 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path310"
d="m 173.495,92.269 c 0,0.991 0,1.982 0,2.972 -0.053,0 -0.105,0 -0.158,0 0.103,-0.94 -0.206,-2.291 0.158,-2.972 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path312"
d="m 8.965,93.364 c 0.361,0.474 0.055,1.614 0.156,2.346 -0.357,-0.268 -0.059,-1.193 -0.156,-1.72 0,-0.208 0,-0.417 0,-0.626 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path314"
d="m 88.258,174.534 c 0.525,0.099 1.451,-0.201 1.721,0.157 -0.574,0 -1.148,0 -1.721,0 0,-0.053 0,-0.105 0,-0.157 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path316"
d="m 93.733,174.691 c 0.268,-0.358 1.193,-0.058 1.719,-0.157 0,0.052 0,0.104 0,0.157 -0.573,0 -1.147,0 -1.719,0 z" /><path
style="clip-rule:evenodd;fill:#dae9e7;fill-rule:evenodd"
id="path318"
d="m 87.475,25.332 c 1.93,-0.261 4.953,-0.261 6.883,0 -2.293,0 -4.588,0 -6.883,0 z" /><path
style="clip-rule:evenodd;fill:#a4cdc8;fill-rule:evenodd"
id="path320"
d="m 24.135,88.203 c 0,2.503 0,5.005 0,7.507 -0.261,-2.138 -0.261,-5.368 0,-7.507 z" /><path
style="clip-rule:evenodd;fill:#a4cdc8;fill-rule:evenodd"
id="path322"
d="m 88.883,9.692 c 1.564,0 3.127,0 4.691,0 0,0.052 0,0.104 0,0.156 -1.564,0 -3.127,0 -4.691,0 0,-0.052 0,-0.103 0,-0.156 z" /><path
style="clip-rule:evenodd;fill:#71aea7;fill-rule:evenodd"
id="path324"
d="m 173.495,88.673 c 0,0.991 0,1.98 0,2.971 -0.363,-0.68 -0.055,-2.031 -0.158,-2.971 0.052,0 0.105,0 0.158,0 z" /><path
style="clip-rule:evenodd;fill:#a4cdc8;fill-rule:evenodd"
id="path326"
d="m 157.698,88.829 c 0.262,1.722 0.262,4.535 0,6.256 0,-2.085 0,-4.171 0,-6.256 z" /></g></svg>
#!/bin/bash
#
# Copyright © 2016 Yannick Loiseau <me@yloiseau.net>
# This work is free. You can redistribute it and/or modify it under the
# terms of the Do What The Fuck You Want To Public License, Version 2,
# as published by Sam Hocevar. See http://www.wtfpl.net/ for more details.
#
#==============================================================================
# Script to check if you are working on a project with Watson and display a
# notification when:
# - you are working on the same project for more than $ALERT_TIME (seconds)
# - you are not working on a project
#
# The purpose is to remind you to start tracking your time, or to check is you
# have forgotten to change the project (and remind you to take a break).
#
# Dependencies:
# - Watson: http://tailordev.github.io/Watson/
# - notify-send: (libnotify-bin on Debian)
#
# Usage:
# 1. Customize the alert message and time.
# 1a. Customize DISPLAY if needed
# 2. Set a cron task to run the script. E.g. (every 5min)
#
# */5 * * * * $HOME/bin/watson-notify
#
#==============================================================================
set -e
ALERT_TIME=7200 # 2 hours
ALERT_MESSAGE="Still working on %s?\nTime for a break."
ALERT_NOTIF="-u low -t 5000"
QUESTION_MESSAGE="What are you doing?"
QUESTION_NOTIF="-u critical -t 10000"
WATSON_STATUS="python3 -m watson status"
NOTIFY="notify-send"
export DISPLAY=:0
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$WATSON_STATUS |
sed -r '
s!^Project !!g;
s!([^ ]+).+started .* ago \(([^)]+)\)!\1 \2!g
' | while read name date; do
if [ $name == "No" -a "$date" == "project started" ] ; then
$NOTIFY $QUESTION_NOTIF "Watson" "$QUESTION_MESSAGE"
exit 0
fi
now=$(date +%s)
ts=$(date -d "$(echo $date | tr '.' '-')" +%s)
duration=$((now - ts))
if [ $duration -ge $ALERT_TIME ] ; then
$NOTIFY $ALERT_NOTIF "Watson" "$(printf "$ALERT_MESSAGE" $name)"
fi
done
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""Check for current Watson project and display a notification when:
- you are working on the same project for more than the maximum duration.
- you are not working on a project.
The maximum duration defaults to 120 minutes and can be set with the `-d` resp.
`--max-duration` command line option.
The time (in seconds) for which the notification is displayed can be set with
the `-t` resp. `--timeout` option (defaults to 5 seconds).
Add the following line to your crontab (`crontab -e`), to run this script
every ten minutes from 10-20h on weekdays::
*/10 10-20 * * mon-fri DISPLAY=:0 "$HOME/bin/watson-notify" 2>/dev/null
"""
import argparse
import os
import sys
import arrow
import notify2
from watson import Watson
WARN_MSG = "Still working on <b>{}</b>?\nTime for a break!"
REMIND_MSG = "What are you doing now?"
def main(args=None):
parser = argparse.ArgumentParser()
parser.add_argument('-d', '--max-duration',
metavar='MIN', type=int, default=120,
help='maximum frame duration before suggesting a break '
'(default: %(default)i min.)')
parser.add_argument('-i', '--icon',
metavar='PATH',
help='path to icon to display with notification')
parser.add_argument('-t', '--timeout',
metavar='SEC', type=int, default=5,
help='timeout for notification display (default: %(default)i sec.)')
args = parser.parse_args(sys.argv[1:] if args is None else args)
current = Watson().current
if current:
duration = (arrow.now() - current['start']).total_seconds()
if duration < args.max_duration * 60:
return
cat = "presence.online"
subject = "Long Watson frame duration"
message = WARN_MSG.format(current['project'])
else:
cat = "presence.offline"
subject = "No Watson project running"
message = REMIND_MSG
if not notify2.init('watson-notify'):
return "Could not connect to notification service."
icon = ("file://%s" % os.path.abspath(args.icon) if args.icon
else "notification-message-IM")
n = notify2.Notification(subject, message, icon=icon)
n.set_category(cat)
n.set_urgency(notify2.URGENCY_LOW)
n.set_timeout(args.timeout * 1000)
if not n.show():
return "Failed to send notification"
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]) or 0)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment