Skip to content

Instantly share code, notes, and snippets.

@adeutscher
Last active September 22, 2019 08:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adeutscher/9c600b3dfd9927275e5347a85d09962a to your computer and use it in GitHub Desktop.
Save adeutscher/9c600b3dfd9927275e5347a85d09962a to your computer and use it in GitHub Desktop.
Conky Timer: Proof of Concept

Mechanics

This proof of concept marks a running timer by placing a unix timestamp in a marker file. When a running timer is paused, the difference in seconds between the start time and now is saved to a 'splitx' file. Entries in the splits file are included in the final tally.

Inspired by a question on Reddit: https://www.reddit.com/r/linuxquestions/comments/d7am8l/timer_linked_to_conky_and_keyboard_button_that_is/

Misc. Notes

Manual Usage

  • Start/Pause the timer by running ./toggle.sh
  • Clear the timer by running ./reset.sh
    • Since reset.sh deletes the splits and marker files, the timer is considered to be paused after it is reset.
  • Display the number of seconds elapsed with ./display.sh
  • Display a formatted version of the number of seconds elapsed with ./conky.sh

Keybinding

Using xbindkeys to allow the toggle and reset scripts to be used globally without a terminal. The Arch Wiki was really helpful about the use of this command (https://wiki.archlinux.org/index.php/Xbindkeys).

Note that xbindkeys is not installed by default, at least on Fedora.

I've included the xbindkeysrc file with my configuration in this gist, but due to how I get to F11/F12 on my laptop your machine may be slightly different.

xbindkeys -f xbindkeysrc

To find the keycodes for a particular key, enter the following command:

xbindkeys --key

Conky

To run demo conky:

conky --config conkyrc

The conky configuration is a default config that's only had the scripting in the displayed content nudged.

# A few common items across scripts.
file_splits="./splits"
file_run_marker="./marker"
sound_start="./zelda-ww-menu.mp3"
sound_pause="./jojo-the-world.mp3"
sound_reset="./metal-gear-alarm.mp3"
play_sound()
{
if ! [ -f "${1}" ]; then
echo "Sound file not found: ${1}"
return 1
fi
mpg123 "${1}" 2> /dev/null >&2 &
}
#!/bin/bash
cd "$(dirname "$(readlink -f "${0}")")"
. "./common.sh"
# Throwing in my function for making times look pretty.
__translate_seconds(){
# Translate a time given in seconds (e.g. the difference between two Unix timestamps) to more human-friendly units.
# So far, I've mostly used this in hook functions to give me a display of how long the parent process has lasted.
# Example:
# local __ctime=$(date +%s)
# local __stime=$(stat -c%X /proc/$PPID)
# local __time_output="$(__translate_seconds "$(($__ctime - $__stime))")"
# The optional second argument to this function specifies the format mode.
# Mode and format examples:
# 0: 3 hours, 2 minutes, and 1 second (DEFAULT)
# 1: 3 hours, 2 minutes, 1 second
# 2: 3h 2m 1s
local __num=$1
local __c=0
local __i=0
if [ "${2:-0}" -eq 2 ]; then
# Each "module" should be the unit and the number of that unit until the next phrasing.
local __modules=(s:60 m:60 h:24 d:7 w:52 y:100 c:100)
else
# Each "module" should be a pairing of a name (in plural form),
# the number of that unit until the next phrasing,
# and (optionally) the phrasing of a single unit (in case lopping an 's' off of the end won't cut it)
local __modules=(seconds:60 minutes:60 hours:24 days:7 weeks:52 years:100 centuries:100:century)
fi
local __modules_count="$(wc -w <<< "${__modules[*]}")"
while [ "$__i" -lt "$__modules_count" ]; do
# Cycling through to get values for each unit.
local __value="$(cut -d':' -f2 <<< "${__modules[$__i]}")"
local __mod_value="$(($__num % $__value))"
local __num="$((__num / $__value))"
local __times[$__i]="$__mod_value"
local __c=$(($__c+1))
local __i=$(($__i+1))
if (( ! $__num )); then
break
fi
done
unset __module
local __i=$(($__c-1))
while [ "$__i" -ge "0" ]; do
# Splitting logic for compressed version (mode 2) and
# other phrasings requires much less tangled code.
if [ "${2:-0}" -eq 2 ]; then
# Short, compressed, and space-efficient version.
printf "${__times[$__i]}$(cut -d':' -f1 <<< "${__modules[$__i]}")"
if (( $__i )); then
printf " "
fi
else
# Long version
# Cycling through used units in reverse.
if [ "${2:-0}" -eq 0 ] && (( ! $__i )) && [ "$__c" -gt 1 ]; then
printf "and "
fi
# Handle plural
if [ "${__times[$__i]}" -eq 1 ]; then
# Attempt special singluar unit.
local __s="$(cut -d':' -f3 <<< "${__modules[$__i]}")"
if [ -n "$__s" ]; then
# Singular unit had content.
printf "${__times[$__i]} $__s"
else
# Lop the 's' off of unit plural for singular.
printf "${__times[$__i]} $(cut -d':' -f1 <<< "${__modules[$__i]}" | sed 's/s$//')"
fi
else
# Standard plural.
printf "${__times[$__i]} $(cut -d':' -f1 <<< "${__modules[$__i]}")"
fi
if (( $__i )); then
# Prepare for the next unit.
# If you aren't a fan of the Oxford comma, then take out this line
[ "$__c" -ge 2 ] && printf ","
# Print space. Leave this in.
printf " "
fi
fi
local __i=$(($__i-1))
done
}
t="$(./display.sh)"
if [ "${t}" -gt 0 ]; then
echo "Time: $(__translate_seconds "${t}")"
else
echo "Timer Empty"
fi
if [ -f "${file_run_marker}" ]; then
echo "RUNNING"
else
echo "PAUSED"
fi
-- vim: ts=4 sw=4 noet ai cindent syntax=lua
--[[
Conky, a system monitor, based on torsmo
Any original torsmo code is licensed under the BSD license
All code written since the fork of torsmo is licensed under the GPL
Please see COPYING for details
Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
Copyright (c) 2005-2012 Brenden Matthews, Philip Kovacs, et. al. (see AUTHORS)
All rights reserved.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
]]
conky.config = {
alignment = 'top_left',
background = false,
border_width = 1,
cpu_avg_samples = 2,
default_color = 'white',
default_outline_color = 'white',
default_shade_color = 'white',
draw_borders = false,
draw_graph_borders = true,
draw_outline = false,
draw_shades = false,
use_xft = true,
font = 'DejaVu Sans Mono:size=12',
gap_x = 5,
gap_y = 60,
minimum_height = 5,
minimum_width = 5,
net_avg_samples = 2,
no_buffers = true,
out_to_console = false,
out_to_stderr = false,
extra_newline = false,
own_window = true,
own_window_class = 'Conky',
own_window_type = 'desktop',
stippled_borders = 0,
update_interval = 1.0,
uppercase = false,
use_spacer = 'none',
show_graph_scale = false,
show_graph_range = false
}
conky.text = [[
$hr
${color grey}Timer Proof of Concept$color
${execpi 1 bash ./conky.sh}
$hr
]]
#!/bin/bash
cd "$(dirname "$(readlink -f "${0}")")"
. "./common.sh"
sum=0
if [ -f "${file_splits}" ]; then
for i in $(cat "${file_splits}"); do
sum="$((${sum}+${i}))"
done
fi
if [ -f "${file_run_marker}" ]; then
sum="$((${sum}+($(date "+%s")-$(cat "${file_run_marker}"))))"
fi
echo "${sum}"
#!/bin/bash
cd "$(dirname "$(readlink -f "${0}")")"
. "./common.sh"
rm -f "${file_splits}" "${file_run_marker}"
play_sound "${sound_reset}"
#!/bin/bash
cd "$(dirname "$(readlink -f "${0}")")"
. "./common.sh"
current="$(date "+%s")"
if [ -f "${file_run_marker}" ]; then
# Currently running
# toggle off
echo "Pause"
time_diff="$((${current}-$(cat "${file_run_marker}")))"
[ -n "${time_diff}" ] && echo "${time_diff}" >> "${file_splits}"
rm "${file_run_marker}"
play_sound "${sound_pause}"
else
# Currently not running.
# start
echo "Start"
echo "${current}" > "${file_run_marker}"
play_sound "${sound_start}"
fi
"./toggle.sh"
m:0x10 + c:96
Mod2 + F12
"./reset.sh"
m:0x10 + c:95
Mod2 + F11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment