diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..46514b1 --- /dev/null +++ b/INSTALL @@ -0,0 +1,18 @@ +#!/bin/bash + +#To install using this script: +#chmod 700 INSTALL +#then run by typing ./INSTALL as root or with sudo. +# If you want to install by hand, just copy the commands below the word fi that ends the if statement below. Exclude the exit 0 statement. +if [[ $(whoami) != "root" ]] ; then +echo "Need to be root." +exit 1 +fi + +cp src/talking-clock /usr/bin/talking-clock +chmod 755 /usr/bin/talking-clock +mkdir -p /usr/share/talking-clock/ +cp src/{bell,prepend,15,30,45}.ogg /usr/share/talking-clock/ +cp README.md /usr/share/talking-clock/README.md +exit 0 + diff --git a/README b/README new file mode 100644 index 0000000..796f0ef --- /dev/null +++ b/README @@ -0,0 +1,59 @@ +talking-clock +Written by Storm Dragon + +talking-clock can chime and/or announce the time when called usually by cron. It is highly configurable. It can be set to chime every hour, quarter, hour or half hour. For instructions on editing the crontab file see man crontab. Here are some suggested entries: +#chime every hour between 10:00AM and 10:00PM +0 10-22 * * * talking-clock +#chime every half-hour: +0,30 * * * * talking-clock +#chime every quarter-hour: +0,15,30,45 * * * * talking-clock +talking-clock can modify cron for you. to do so use +talking-clock --cron number +where number is 1 for every hour, 2 for every half-hour, or four for every quarter-hour. Any other entry removes talking-clock settings from, causing talking-clock to not chime at all unless called specifically by you. The --cron switch only allows one argument, using multiple arguments will not work. If you use the --cron argument it must be the first argument follow by only one other argument. + +talking-clock understands the following arguments: +-a --audio Sound command. Command to play sound. the default is play -q provided by the sox package. Another example, if you have vorbis-tools installed would be +ogg123 -q +or +paplay +Note that with the ogg123 command the aplay command is used for the pico voice. Aplay will not work for the rest of the commands because it does not play ogg files. +-b --bell Set path to the sound used for hourly chimes. +-c --nochime Turn off chimes. +-n --nospeak turn off spoken time. +-p --prepend Set the path to a sound that should prepend chimes. +-q --quarterhour Set the path to the sound for quarter-hour chimes. +-s --soundpack Set path to soundpack. Sound packs should be in ogg format and contain 1.ogg, 2.ogg, ... 11.ogg, 12.ogg and 15.ogg, 30.ogg, and 45.ogg for the quarter-hour chimes. +-t --torify anonymously get your current temperature, used with -z --zipcode. +-v --voice Select voice. Default is espeak other options are +cepstral, espeak, festival, flite, flite_time pico, speech-dispatcher and custom. +To set a custom voice enter the command as in: +-v 'espeak -v en-us+klatt2' +zipcode and flite_time are incompatable. If you have zipcode set the temperature will not be read while using flite_time. +-z --zipcode Postal code: Will speak the temperature along with the time so long as you do not have nospeak set. E.G. -z 90210 + +talking clock can also read settings from the following files? +/etc/talking-clockrc global settings +~/.talking-clockrc +Settings for individual users. If both files exist the user specific settings will be used. Command line arguments are considered all powerful and will override all others. + +Configuration files should be written as command=setting. Here is an example of a configuration file: +bell-/home/USER/hourbell.ogg +format=24 +quarter=/home/USER/clocksounds/quarterhour.ogg +sound=play -q +prepend=/home/USER/big-ben.ogg +soundpack=/home/USER/thunderstorm +chime=true +speak=true +zipcode=90210 +torify=true +Soundpack should be the path to a directory. Do not include the trailing / talking-clock adds it for you. +voice=espeak -v en-us+klatt2 -s 300 +Be careful when using custom voice commands, if it is not valid the program will not work. You do not have to specify parameters for voice commands if you want to use the defaults. You can use voice=espeak (this is the default), voice=cepstral, voice=speech-dispatcher, voice=pico, or voice=festival. + +Creating soundpacks is very simple. Make a directory named anything you wish, thunderstorm for example, and place files inside it. The naming scheme for soundpack files follows the hours 1 through 12 and quarter hours 15, 30, 45. Each sound file must be in .ogg format. So, your directory will contain 1.ogg, 2.ogg, ... 12.ogg, 15.ogg, 30.ogg, and 45.ogg. To download or submit soundpacks go to: +http://www.stormdragon.us/talking-clock/ + +If you wish to contact me you can find me on Twitter as @stormdragon2976. Also don't forget to check out my blog located at: +http://www.stormdragon.us/ diff --git a/src/.testrc b/src/.testrc new file mode 100644 index 0000000..abcb743 --- /dev/null +++ b/src/.testrc @@ -0,0 +1,4 @@ +setting1=abc +setting2=-v en-us -s 1280 +setting3-testing + diff --git a/src/15.ogg b/src/15.ogg new file mode 100644 index 0000000..bfe7ea9 Binary files /dev/null and b/src/15.ogg differ diff --git a/src/30.ogg b/src/30.ogg new file mode 100644 index 0000000..e7c5baa Binary files /dev/null and b/src/30.ogg differ diff --git a/src/45.ogg b/src/45.ogg new file mode 100644 index 0000000..aec67ee Binary files /dev/null and b/src/45.ogg differ diff --git a/src/bell.ogg b/src/bell.ogg new file mode 100644 index 0000000..00c041a Binary files /dev/null and b/src/bell.ogg differ diff --git a/src/prepend.ogg b/src/prepend.ogg new file mode 100644 index 0000000..4f58f6a Binary files /dev/null and b/src/prepend.ogg differ diff --git a/src/talking-clock b/src/talking-clock new file mode 100755 index 0000000..405de51 --- /dev/null +++ b/src/talking-clock @@ -0,0 +1,349 @@ +#!/bin/bash + +#talking-clock written by Storm Dragon +#project first created on Wednesday, March 23, 2011 +#license WTFPL: http://wtfpl.net + +#Create or modify cron jobs +if [ "$1" == "--cron" ] ; then + if [ "$#" -ne "2" ] ; then + echo -e "Invalid cron option:\n"\ + "to set a cron enter:\n"\ + "talking-clock --cron chimes-per-hour\n"\ + "If you would like cron to chime 4 times per hour (every quarter hour) you would enter:\n"\ + "talking-clock --cron 4\n"\ + "Valid entries are 1, 2, and 4. Anything else causes the cron to be removed if it exists.\n"\ + "After you have made changes you can use the command:\n"\ + "crontab -l\n"\ + "to view your settings." + exit 1 + fi + crontab -l > /tmp/cron.bak + read -p "You are about to modify talking-clock settings. Are you sure you want to do this? (Only y or Y confirms, anything else cancels) ", answer + if [[ "$answer" != "y" && "$answer" != "Y" ]] ; then + echo "talking-clock settings unchanged." + exit 0 + fi + sed -i -r '/^.*talking-clock.*$/d' /tmp/cron.bak + newCron=$(cat /tmp/cron.bak) + case "$2" in + "1") + #Chime once per hour. + newCron="$newCron\n#talking-clock settings\n0 * * * * talking-clock > /dev/null" + ;; + "2") + #Chime twice per hour. + newCron="$newCron\n#talking-clock settings\n0,30 * * * * talking-clock > /dev/null" + ;; + "4") + #Chime four times per hour. + newCron="$newCron\n#talking-clock settings\n0,15,30,45 * * * * talking-clock > /dev/null" + esac + #write new cron to temperary file. + echo -e "$newCron" > /tmp/cron.bak + #install the new cron file. + if [ -f /tmp/cron.bak ] ; then + crontab /tmp/cron.bak + echo "talking-clock settings updated." + exit 0 + fi + exit 0 +fi + +#initialize variables +hour=$(date +'%-l') +minute=$(date +'%-M') +timeOfDay=$(date +'%p' | sed 's/AM/A M/') +#Default sound to play on half hour *:30 +quarterHourChime="/usr/share/talking-clock/bell.ogg" +#Default sound to play on hours +hourChime="/usr/share/talking-clock/bell.ogg" +#play chimes? +chime="true" +#command used to play sounds +soundCommand="play -qV0" +#default voice for speaking time is espeak +voice="espeak" +#should the time be spoken? +speakTime="true" + +#Check for settings files in order of importants +if [ -f "$HOME/.talking-clockrc" ] ; then + #Read from local settings + confFile="$HOME/.talking-clockrc" +elif [ -f "/etc/talking-clockrc" ] ; then + #Read from global settings + confFile="/etc/talking-clockrc" +fi + +#read from configuration file if it exists +if [ -n "$confFile" ] ; then + #use varCheck to test if the variable is set in the file + #if it is, set it to the correct variable, if not use the default. + #check for 24 hour time format + varCheck="$(grep -i '^format=24' "$confFile")" + if [ -n "$varCheck" ] ; then + format="24" + fi + #check for hour chime in file + varCheck=$(grep -i '^bell=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + hourChime="$varCheck" + fi + #check for quarter-hour chime in file + varCheck=$(grep -i '^quarter=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + quarterHourChime="$varCheck" + fi + #check for prepended sound + varCheck=$(grep -i '^prepend=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + prependSound="$varCheck" + fi + #check for command to play sounds + varCheck=$(grep -i '^sound=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + soundCommand="$varCheck" + fi + #get the voice used to speak time + varCheck=$(grep -i '^voice=' "$confFile" | cut -d = -f 2 | tr -d "&;<>\"|\$\)\(") + if [ -n "$varCheck" ] ; then + voice="$varCheck" + fi + #check for zipcode for current temperature + varCheck=$(grep -i '^zipcode=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + zipcode="$varCheck" + fi + #check for soundpack directory + varCheck=$(grep -i '^soundpack=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + soundPack="$varCheck" + fi + #Check for tor mode + varCheck=$(grep -i '^torify=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + torify="$varCheck" + fi + #Check for no speech mode + varCheck=$(grep -i '^speak=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + speakTime="$varCheck" + fi + #Check for no chime mode + varCheck=$(grep -i '^chime=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + chime="$varCheck" + fi +fi + +#Get and process commandline args which override all other settings. +while [ $# -gt 0 ] ; do + case "$1" in + "-a" | "--audio") + shift + soundCommand="$1" + ;; + "-q" | "--quarterhour") + shift + if [ -f "$1" ] ; then + quarterHourChime="$1" + else + echo "File $1 not found." + exit 1 + fi + ;; + "-b" | "--bell") + shift + if [ -f "$1" ] ; then + hourChime="$1" + else + echo "File $1 not found." + exit 1 + fi + ;; + "-f" | "--format") + shift + if [ "$1" == "12" -o "$1" == "24" ] ; then + if [ $1 -eq 24 ] ; then + format="24" + fi + else + echo "Invalid time format: Valid options are 12 and 24." + exit 1 + fi + ;; + "-p" | "--prepend") + shift + if [ -f "$1" ] ; then + prependSound="$1" + else + echo "File $1 not found." + exit 1 + fi + ;; + "-s" | "--soundpack") + shift + if [ -d "$1" ] ; then + soundPack="$1" + else + echo "Directory $1 does not exist." + exit 1 + fi + ;; + "-n" | "--nospeak") + speakTime="false" + ;; + "-t" | "--torify") + torify="true" + ;; + "-c" | "--nochime") + chime="false" + ;; + "-v" | "--voice") + shift + voice="$1" + ;; + "-z" | "--zipcode") + shift + zipcode="$1" + ;; + *) + echo -e "Talking-clock by Storm Dragon\nTalking-clock accepts the following arguments:\n--cron number:\nIf you use --cron the only valid entry is a number following it. 1 will cause the clock to chime every hour, 2 every\nhalf-hour, 4 every quarter, and anything else will delete your existing settings if they exist.\n-a --audio Command for playing sound. The default is play -q provided from the sox package.\n-b --bell Set path to the sound used for hourly chimes.\n-c --nochime Turn off chimes.\n-f --format: 12 or 24 hour format. Default is 12 hour time.\n-n --nospeak turn off spoken time.\n-p --prepend Select a sound file to be played before chiming.\n-q --quarterhour Set the path to the sound for quarter-hour chimes.\n-s --soundpack Set path to soundpack. Sound packs should be in ogg format and contain 1.ogg, 2.ogg, ... 11.ogg, 12.ogg and\nquarter.ogg for the quarter-hour chime.\n-v --voice Select voice. Default is espeak other options are\ncepstral, espeak, festival, pico, speech-dispatcher and custom.\nTo set a custom voice enter the command as in:\n-v 'espeak -v en-us+klatt2'\n-t --torify retrieve temperature anonymously using torify, used with -z --zipcode\n-z --zipcode postal code Used for current temperature, may not be available inn all areas.\nFor complete information read the README located at /usr/share/talking-clock/README" + exit 0 + esac + shift +done + +#Speak the time +#Safely create voice files for tts who write to file +voiceFile="$(mktemp --tmpdir tlkclkXXXX.wav)" +if [ "$speakTime" == "true" ] ; then + if [ "$minute" -eq "0" ] ; then + timeString="$hour o clock $timeOfDay" + elif [ "$minute" -lt "10" ] ; then + timeString="$hour o $minute $timeOfDay" + else + timeString="$hour $minute $timeOfDay" + fi + #if 24 time is set, override the above with correct settings. + if [ -n "$format" ] ; then + #Make it read purdy for speech synthesizers. + timeString="$(date +'%H:%M' | sed -e 's/^00:00$/zero hundred hours/' -e 's/:00$/ hundred hours/' -e 's/:0/ o /' -e 's/^0//')" + else + timeString="$(echo "$timeString" | sed -e 's/^0//' -e 's/^10/ten/' -e 's/^11/eleven/' -e 's/^12/twelve/')" + fi + #Add temperature if zipcode is set + if [ -n "$zipcode" ] ; then + if [ "$torify" == "true" ] ; then + temperature="$(torify curl -s "http://weather.yahooapis.com/forecastrss?p=${zipcode}&u=f" | grep -A 1 "Current Conditions:" | tr -Cd '[:digit:]-')" + else + temperature="$(curl -s "http://weather.yahooapis.com/forecastrss?p=${zipcode}&u=f" | grep -A 1 "Current Conditions:" | tr -Cd '[:digit:]-')" + fi + if [ -n "$temperature" ] ; then + timeString="$timeString $temperature degrees." + timeString="$(echo "$timeString" | sed -e 's/-/negative /')" + fi + fi + case "$voice" in + "cepstral") + swift -o $voiceFile "$timeString" + #If the default sound command is used write time to file and normalize it before playing, cause Cepstral is kind of low volume. + if [ "$soundCommand" == "play -qV0" ] ; then + $soundCommand $voiceFile norm + else + $soundCommand $voiceFile + fi + ;; + "espeak") + espeak -v en-us -a 175 "$timeString" + ;; + "festival") + #If the default sound command is used write time to file and normalize it before playing, cause festival is kind of low volume. + if [ "$soundCommand" == "play -qV0" ] ; then + echo "$timeString" | text2wave -o $voiceFile + $soundCommand $voiceFile norm + else + echo "$timeString" | festival --tts + fi + ;; + "flite") + #For some reason flite has trouble with ##:## format. + echo "$timeString" | flite + ;; + "googletts") + /usr/bin/translate -speak -b "$timeString" + ;; + "flite_time") + flite_time $(date +'%H:%M') &> /dev/null + ;; + "speech-dispatcher") + spd-say -w -P important "$timeString" + ;; + "pico") + pico2wave -w $voiceFile "$timeString" + #ogg123 doesn't do wav, so hopefully everyone has aplay... + if [[ "$soundCommand" == "ogg123" || "$soundCommand" == "ogg123 -q" ]] ; then + aplay -q $voiceFile + else + $soundCommand $voiceFile + fi + ;; + *) + $voice "$timeString" + esac + rm $voiceFile +fi + +#Play the prepended sound if one is selected +#There will be a slight gap between the prepended sound and the actual chiming. +#This is to simulate real clocks based on my experience. +if [ "$minute" -eq "0" ]; then + if [ -n "$prependSound" ] ; then + $soundCommand "$prependSound" + fi +fi + +#chime for quarter hour +if [[ "$minute" -eq "15" || "$minute" -eq "30" || "$minute" -eq "45" ]] ; then + #Play correct sound pack file if we are using sound packs + if [ -n "$soundPack" ] ; then + quarterHourChime="$soundPack/$minute.ogg" + else + quarterHourChime="/usr/share/talking-clock/$minute.ogg" + fi + #Play sound for half-hour + if [ $chime != "false" ] ; then + $soundCommand "$quarterHourChime" + fi +fi + +#Chime on the hour +if [ "$minute" -eq "0" ] ; then + #Check if we are using a soundpack + if [ -z "$soundPack" ] ; then + if [ $chime != "false" ] ; then + i=0 + #create chime string for sound players that can handle more than one sound argument. + soundString="" + while [ "$i" -lt "$hour" ] ; do + if [[ "$soundCommand" == "play" || "$soundCommand" == "play -q" || "$soundCommand" == "ogg123" || "$soundCommand" == "ogg123 -q" ]] ; then + soundString="$soundString $hourChime" + else + $soundCommand "$hourChime" + fi + i=$(($i + 1)) + done + if [ -n "$soundString" ] ; then + #No quotes around soundString here because it will not work. + $soundCommand $soundString + fi + fi + else + if [ $chime != "false" ] ; then + $soundCommand "$soundPack/$hour.ogg" + fi + fi +fi +exit 0 + diff --git a/src/talking-clock.bak b/src/talking-clock.bak new file mode 100755 index 0000000..2d23aea --- /dev/null +++ b/src/talking-clock.bak @@ -0,0 +1,344 @@ +#!/bin/bash + +#talking-clock written by Storm Dragon +#project first created on Wednesday, March 23, 2011 +#license WTFPL: http://wtfpl.net + +#Create or modify cron jobs +if [ "$1" == "--cron" ] ; then + if [ "$#" -ne "2" ] ; then + echo -e "Invalid cron option:\n"\ + "to set a cron enter:\n"\ + "talking-clock --cron chimes-per-hour\n"\ + "If you would like cron to chime 4 times per hour (every quarter hour) you would enter:\n"\ + "talking-clock --cron 4\n"\ + "Valid entries are 1, 2, and 4. Anything else causes the cron to be removed if it exists.\n"\ + "After you have made changes you can use the command:\n"\ + "crontab -l\n"\ + "to view your settings." + exit 1 + fi + crontab -l > /tmp/cron.bak + read -p "You are about to modify talking-clock settings. Are you sure you want to do this? (Only y or Y confirms, anything else cancels) ", answer + if [[ "$answer" != "y" && "$answer" != "Y" ]] ; then + echo "talking-clock settings unchanged." + exit 0 + fi + sed -i -r '/^.*talking-clock.*$/d' /tmp/cron.bak + newCron=$(cat /tmp/cron.bak) + case "$2" in + "1") + #Chime once per hour. + newCron="$newCron\n#talking-clock settings\n0 * * * * talking-clock > /dev/null" + ;; + "2") + #Chime twice per hour. + newCron="$newCron\n#talking-clock settings\n0,30 * * * * talking-clock > /dev/null" + ;; + "4") + #Chime four times per hour. + newCron="$newCron\n#talking-clock settings\n0,15,30,45 * * * * talking-clock > /dev/null" + esac + #write new cron to temperary file. + echo -e "$newCron" > /tmp/cron.bak + #install the new cron file. + if [ -f /tmp/cron.bak ] ; then + crontab /tmp/cron.bak + echo "talking-clock settings updated." + exit 0 + fi + exit 0 +fi + +#initialize variables +hour=$(date +'%-l') +minute=$(date +'%-M') +timeOfDay=$(date +'%p' | sed 's/AM/A M/') +#Default sound to play on half hour *:30 +quarterHourChime="/usr/share/talking-clock/bell.ogg" +#Default sound to play on hours +hourChime="/usr/share/talking-clock/bell.ogg" +#play chimes? +chime="true" +#command used to play sounds +soundCommand="play -qV0" +#default voice for speaking time is espeak +voice="espeak" +#should the time be spoken? +speakTime="true" + +#Check for settings files in order of importants +if [ -f "$HOME/.talking-clockrc" ] ; then + #Read from local settings + confFile="$HOME/.talking-clockrc" +elif [ -f "/etc/talking-clockrc" ] ; then + #Read from global settings + confFile="/etc/talking-clockrc" +fi + +#read from configuration file if it exists +if [ -n "$confFile" ] ; then + #use varCheck to test if the variable is set in the file + #if it is, set it to the correct variable, if not use the default. + #check for 24 hour time format + varCheck="$(grep -i '^format=24' "$confFile")" + if [ -n "$varCheck" ] ; then + format="24" + fi + #check for hour chime in file + varCheck=$(grep -i '^bell=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + hourChime="$varCheck" + fi + #check for quarter-hour chime in file + varCheck=$(grep -i '^quarter=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + quarterHourChime="$varCheck" + fi + #check for prepended sound + varCheck=$(grep -i '^prepend=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + prependSound="$varCheck" + fi + #check for command to play sounds + varCheck=$(grep -i '^sound=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + soundCommand="$varCheck" + fi + #get the voice used to speak time + varCheck=$(grep -i '^voice=' "$confFile" | cut -d = -f 2 | tr -d "&;<>\"|\$\)\(") + if [ -n "$varCheck" ] ; then + voice="$varCheck" + fi + #check for zipcode for current temperature + varCheck=$(grep -i '^zipcode=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + zipcode="$varCheck" + fi + #check for soundpack directory + varCheck=$(grep -i '^soundpack=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + soundPack="$varCheck" + fi + #Check for tor mode + varCheck=$(grep -i '^torify=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + torify="$varCheck" + fi + #Check for no speech mode + varCheck=$(grep -i '^speak=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + speakTime="$varCheck" + fi + #Check for no chime mode + varCheck=$(grep -i '^chime=' "$confFile" | cut -d = -f 2) + if [ -n "$varCheck" ] ; then + chime="$varCheck" + fi +fi + +#Get and process commandline args which override all other settings. +while [ $# -gt 0 ] ; do + case "$1" in + "-a" | "--audio") + shift + soundCommand="$1" + ;; + "-q" | "--quarterhour") + shift + if [ -f "$1" ] ; then + quarterHourChime="$1" + else + echo "File $1 not found." + exit 1 + fi + ;; + "-b" | "--bell") + shift + if [ -f "$1" ] ; then + hourChime="$1" + else + echo "File $1 not found." + exit 1 + fi + ;; + "-f" | "--format") + shift + if [ "$1" == "12" -o "$1" == "24" ] ; then + if [ $1 -eq 24 ] ; then + format="24" + fi + else + echo "Invalid time format: Valid options are 12 and 24." + exit 1 + fi + ;; + "-p" | "--prepend") + shift + if [ -f "$1" ] ; then + prependSound="$1" + else + echo "File $1 not found." + exit 1 + fi + ;; + "-s" | "--soundpack") + shift + if [ -d "$1" ] ; then + soundPack="$1" + else + echo "Directory $1 does not exist." + exit 1 + fi + ;; + "-n" | "--nospeak") + speakTime="false" + ;; + "-t" | "--torify") + torify="true" + ;; + "-c" | "--nochime") + chime="false" + ;; + "-v" | "--voice") + shift + voice="$1" + ;; + "-z" | "--zipcode") + shift + zipcode="$1" + ;; + *) + echo -e "Talking-clock by Storm Dragon\nTalking-clock accepts the following arguments:\n--cron number:\nIf you use --cron the only valid entry is a number following it. 1 will cause the clock to chime every hour, 2 every\nhalf-hour, 4 every quarter, and anything else will delete your existing settings if they exist.\n-a --audio Command for playing sound. The default is play -q provided from the sox package.\n-b --bell Set path to the sound used for hourly chimes.\n-c --nochime Turn off chimes.\n-f --format: 12 or 24 hour format. Default is 12 hour time.\n-n --nospeak turn off spoken time.\n-p --prepend Select a sound file to be played before chiming.\n-q --quarterhour Set the path to the sound for quarter-hour chimes.\n-s --soundpack Set path to soundpack. Sound packs should be in ogg format and contain 1.ogg, 2.ogg, ... 11.ogg, 12.ogg and\nquarter.ogg for the quarter-hour chime.\n-v --voice Select voice. Default is espeak other options are\ncepstral, espeak, festival, pico, speech-dispatcher and custom.\nTo set a custom voice enter the command as in:\n-v 'espeak -v en-us+klatt2'\n-t --torify retrieve temperature anonymously using torify, used with -z --zipcode\n-z --zipcode postal code Used for current temperature, may not be available inn all areas.\nFor complete information read the README located at /usr/share/talking-clock/README" + exit 0 + esac + shift +done + +#Speak the time +#Safely create voice files for tts who write to file +voiceFile="$(mktemp --tmpdir tlkclkXXXX.wav)" +if [ "$speakTime" == "true" ] ; then + if [ "$minute" -eq "0" ] ; then + timeString="$hour o clock $timeOfDay" + elif [ "$minute" -lt "10" ] ; then + timeString="$hour o $minute $timeOfDay" + else + timeString="$hour $minute $timeOfDay" + fi + #if 24 time is set, override the above with correct settings. + if [ -n "$format" ] ; then + #Make it read purdy for speech synthesizers. + timeString="$(date +'%H:%M' | sed -e 's/^00:00$/zero hundred hours/' -e 's/:00$/ hundred hours/' -e 's/:0/ o /' -e 's/^0//')" + else + timeString="$(echo "$timeString" | sed -e 's/^0//' -e 's/^10/ten/' -e 's/^11/eleven/' -e 's/^12/twelve/')" + fi + #Add temperature if zipcode is set + if [ -n "$zipcode" ] ; then + if [ "$torify" == "true" ] ; then + temperature="$(torify curl -s "http://weather.yahooapis.com/forecastrss?p=${zipcode}&u=f" | grep -A 1 "Current Conditions:" | tr -Cd '[:digit:]-')" + else + temperature="$(curl -s "http://weather.yahooapis.com/forecastrss?p=${zipcode}&u=f" | grep -A 1 "Current Conditions:" | tr -Cd '[:digit:]-')" + fi + if [ -n "$temperature" ] ; then + timeString="$timeString $temperature degrees." + timeString="$(echo "$timeString" | sed -e 's/-/negative /')" + fi + fi + case "$voice" in + "cepstral") + swift -o $voiceFile "$timeString" + #If the default sound command is used write time to file and normalize it before playing, cause Cepstral is kind of low volume. + if [ "$soundCommand" == "play -qV0" ] ; then + $soundCommand $voiceFile norm + else + $soundCommand $voiceFile + fi + ;; + "espeak") + espeak -v en-us "$timeString" + ;; + "festival") + #If the default sound command is used write time to file and normalize it before playing, cause festival is kind of low volume. + if [ "$soundCommand" == "play -qV0" ] ; then + echo "$timeString" | text2wave -o $voiceFile + $soundCommand $voiceFile norm + else + echo "$timeString" | festival --tts + fi + ;; + "flite") + #For some reason flite has trouble with ##:## format. + echo "$timeString" | flite + ;; + "flite_time") + flite_time $(date +'%H:%M') &> /dev/null + ;; + "speech-dispatcher") + spd-say -w -P important "$timeString" + ;; + "pico") + pico2wave -w $voiceFile "$timeString" + #ogg123 doesn't do wav, so hopefully everyone has aplay... + if [[ "$soundCommand" == "ogg123" || "$soundCommand" == "ogg123 -q" ]] ; then + aplay -q $voiceFile + else + $soundCommand $voiceFile + fi + ;; + *) + $voice "$timeString" + esac + rm $voiceFile +fi + +#Play the prepended sound if one is selected +#There will be a slight gap between the prepended sound and the actual chiming. +#This is to simulate real clocks based on my experience. +if [[ "$minute" -eq "0" || "$minute" -eq "15" || "$minute" -eq "30" || "$minute" -eq "45" ]] ; then + if [ -n "$prependSound" ] ; then + $soundCommand "$prependSound" + fi +fi + +#chime for quarter hour +if [[ "$minute" -eq "15" || "$minute" -eq "30" || "$minute" -eq "45" ]] ; then + #Play correct sound pack file if we are using sound packs + if [ -n "$soundPack" ] ; then + quarterHourChime="$soundPack/$minute.ogg" + fi + #Play sound for half-hour + if [ $chime != "false" ] ; then + $soundCommand "$quarterHourChime" + fi +fi + +#Chime on the hour +if [ "$minute" -eq "0" ] ; then + #Check if we are using a soundpack + if [ -z "$soundPack" ] ; then + if [ $chime != "false" ] ; then + i=0 + #create chime string for sound players that can handle more than one sound argument. + soundString="" + while [ "$i" -lt "$hour" ] ; do + if [[ "$soundCommand" == "play" || "$soundCommand" == "play -q" || "$soundCommand" == "ogg123" || "$soundCommand" == "ogg123 -q" ]] ; then + soundString="$soundString $hourChime" + else + $soundCommand "$hourChime" + fi + i=$(($i + 1)) + done + if [ -n "$soundString" ] ; then + #No quotes around soundString here because it will not work. + $soundCommand $soundString + fi + fi + else + if [ $chime != "false" ] ; then + $soundCommand "$soundPack/$hour.ogg" + fi + fi +fi +exit 0 + diff --git a/talking-clock-gui/README b/talking-clock-gui/README new file mode 100644 index 0000000..24189ac --- /dev/null +++ b/talking-clock-gui/README @@ -0,0 +1,4 @@ +talking-clock-gui is a graphical interface to talking-clock. It is released under the same license as talking-clock, the GPL. +Requirements are talking-clock and yad http://code.google.com/p/yad/ +If you need to contact me I am on Identica and Twitter as stormdragon2976. You can also use the contact form on my blog: +http://www.stormdragon.us/ diff --git a/talking-clock-gui/talking-clock-gui b/talking-clock-gui/talking-clock-gui new file mode 100755 index 0000000..fa08147 --- /dev/null +++ b/talking-clock-gui/talking-clock-gui @@ -0,0 +1,199 @@ +#!/bin/bash +#GUI for the talking-clock program +#Written by Storm Dragon +#Tuesday, August 28, 2012 +#license GPL + +chime_settings() +{ + #get how often the clock should chime. + chimeInterval=$(yad --form --field="Chime:cb" --separator="" --title="Talking Clock" --text="Please select how often you would like talking-clock to chime:" 'Disable!Hourly!Every Half Hour!Every Quarter Hour') + case "$chimeInterval" in + 'Disable') + chimeInterval=0 + ;; + 'Hourly') + chimeInterval=1 + ;; + 'Every Half Hour') + chimeInterval=2 + ;; + 'Every Quarter Hour') + chimeInterval=4 + ;; + esac + #if [[ $chimeInterval -ge 1 && $chimeInterval -le 4 ]] ; then + echo "talking-clock --cron $chimeInterval" + #fi +} + +read_settings() +{ + #Initialize variables to defaults before reading existing settings if any + chime="true" + speak="true" + voice=espeak + if [ -e "$confFile" ] ; then + if [ -w "$confFile" ] ; then + bell="$(grep -i 'bell=' "$confFile" | cut -d = -f 2)" + prepend="$(grep -i 'prepend=' "$confFile" | cut -d = -f 2)" + quarter="$(grep -i 'quarter=' "$confFile" | cut -d = -f 2)" + sound="$(grep -i 'sound=' "$confFile" | cut -d = -f 2)" + soundpack="$(grep -i 'soundpack=' "$confFile" | cut -d = -f 2)" + voice="$(grep -i 'voice=' "$confFile" | cut -d = -f 2)" + zipcode="$(grep -i 'zipcode=' "$confFile" | cut -d = -f 2)" + else + yad --error --title="Talking Clock" --text="There was an error reading the settings file. Exiting." + exit 1 + fi + fi +} + +sound_settings() +{ + #Initialize soundMenu variable + soundMenu=0 + while [ $soundMenu -ne 7 ] ; do + #Set soundMenu variable e so it will exit properly if nothing is chosen. + soundMenu=7 + #get current setting of speak and chime options to make menu display correctly. + if [ "$chime" == "true" ] ; then + chimeSetting="Disable" + else + chimeSetting="Enable" + fi + if [ "$speak" == "true" ] ; then + speakSetting="Disable" + else + speakSetting="Enable" + fi + #Generate the menu for all sound options + yad --title="Talking Clock Sound Settings" --text="select an option:" --button="$chimeSetting _Chimes:1" --button="$speakSetting _Speech:2" --button="_Bell:3" --button="_Quarter Hour:4" --button="_Prepend:5" --button="_Soundpack:6" --button="_Main Menu:7" + soundMenu=$? + #adjust sounds preferences based on the above menu option. + case $soundMenu in + 1) + if [ "$chime" == "true" ] ; then + chime="false" + else + chime="true" + fi + ;; + 2) + if [ -n "$zipcode" ] ; then + yad --error --title="Talking Clock" --text="You must clear the postal code before disabling speech. To do so, select weather from the main menu, and leave the postal code field blank." + fi + if [ "$speak" == "true" -a -z "$zipcode" ] ; then + speak="false" + else + speak="true" + fi + ;; + 3) + bell="$(yad --file-selection --title="Select An Hourly chime sound" --file-filter="*.ogg")" + if [ -n "$bell" ] ; then + soundpack="" + fi + ;; + 4) + quarter="$(yad --file-selection --title="Select A Quarter Hour chime sound" --file-filter="*.ogg")" + if [ -n "$quarter" ] ; then + soundpack="" + fi + ;; + 5) + prepend="$(yad --file-selection --title="Select a sound to play before each chime" --file-filter="*.ogg")" + ;; + 6) + soundpack="$(yad --file-selection --title="Select the directory that contains the soundpack" --directory)" + if [ -n "$soundpack" ] ; then + bell="" + quarter="" + fi + ;; + esac + done +} + +voice_settings() +{ + voice="$(yad --form --separator="" --field="voice:cb" --title="Talking Clock" --text="Please select a voice for Talking Clock to use:" 'cepstral!espeak!festival!pico!custom')" + echo "$voice" + if [ "$voice" == "custom" ] ; then + voice="$(yad --entry --title="Talking Clock" --text="Please enter custom voice command:")" + fi +} + +weather_settings() +{ + zipcode="$(yad --entry --title="Talking Clock Weather Settings" --text="Please enter your postal code:")" + if [ -n "$zipcode" ] ; then + speak="true" + fi +} + +write_settings() +{ + #Make sure the file either doesn't exist, or we have write permissions + if [ ! -e "$confFile" -o -r "$confFile" ] ; then + echo -e "chime=$chime\nspeak=$speak" > $confFile + if [ -n "$bell" ] ; then + echo "bell=$bell" >> $confFile + fi + if [ -n "$prepend" ] ; then + echo -e "prepend=$prepend" >> $confFile + fi + if [ -n "$quarter" ] ; then + echo -e "quarter=$quarter" >> $confFile + fi + if [ -n "$sound" ] ; then + echo -e "sound=$sound" >> $confFile + fi + if [ -n "$soundpack" ] ; then + echo -e "soundpack=$soundpack" >> $confFile + fi + if [ -n "$voice" ] ; then + echo -e "voice=$voice" >> $confFile + fi + if [ -n "$zipcode" ] ; then + echo -e "zipcode=$zipcode" >> $confFile + fi + fi +} + +#Main section loop +#find out if changes are system wide, or fo local user. +if [ "$(whoami)" == "root" ] ; then +confFile="/etc/talking-clockrc" +else +confFile="$HOME/.talking-clockrc" +fi +#initialize settings +read_settings +#initialize menu variable +menu=0 +while [ $menu -lt 5 ] ; do +#Set menu to exit code incase the window is closed without an option being selected +menu=5 +yad --title="Talking Clock" --text="Select an option:" --button="_Chime Settings:1" --button="_Sounds and Soundpacks:2" --button="_Voice:3" --button="_Weather:4" --button="Cance_l:5" --button="S_ave Settings:6" +menu=$? +case "$menu" in + 1) + chime_settings + ;; + 2) + sound_settings + ;; + 3) + voice_settings + ;; + 4) + weather_settings + ;; + 6) + write_settings + ;; + *) + exit 0 +esac +done