A long while ago, I had a clock set to say things like morning, day, evening, night, for time in a panel app. Broad stroke, not very specific, It might have been a KDE desktop. I am in Ubuntu Mate now, is there a way to get this vague time description in the mate panel?
Textual / speaking clock for Mate and other Ubuntu variants
Although the question was originally about Ubuntu Mate, luckily, from 15.10, indicators can be used on
Mateas well. As a result, the answer below at least works for
Mate and (tested) on
A GUI to change settings is still to follow (working on it), but I tested the indicator below for at least 20 hrs, and (as expected) it did the job without an error.
The indicator offers the following options:
Show the textual time
Show the textual "day-area" (night, morning, day, evening)
Show a.m. / p.m.
Show all of them at once (or any combination of the three)
Speak out the time every quarter of an hour (
Optionally, the time is displayed fuzzy; rounded on five minutes, e.g.
quarter to eleven.
The script, the module and an icon
The solution exists of a script, a separate module and an icon, which you need to store in one and the same directory.
Right-clck on it and save it as (exactly)
This is the module that produces the textual time and all other displayed information. Copy the code, save it as (again, exactly)
tcalc.py, together with the icon above in one and the same directory.
#!/usr/bin/env python3 import time # --- set starttime of morning, day, evening, night (whole hrs) limits = [6, 9, 18, 21] # --- periods = ["night", "morning", "day", "evening", "night"] def __fig(n): singles = [ "midnight", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen", "fourteen", "quarter", "sixteen", "seventeen", "eighteen", "nineteen", ] tens = ["twenty", "half"] if n < 20: return singles[n] else: if n%10 == 0: return tens[int((n/10)-2)] else: fst = tens[int(n/10)-2] lst = singles[int(str(n)[-1])] return fst+"-"+lst def __fuzzy(currtime): minutes = round(currtime/5)*5 if minutes == 60: currtime = 0 currtime = currtime + 1 else: currtime = minutes currtime = 0 if currtime == 24 else currtime return currtime def textualtime(fuzz): currtime = [int(n) for n in time.strftime("%H %M %S").split()] currtime = __fuzzy(currtime) if fuzz == True else currtime speak = True if currtime%15 == 0 else False period = periods[len([n for n in limits if currtime >= n])] # define a.m. / p.m. if currtime >= 12: daytime = "p.m." if currtime == 12: if currtime > 30: currtime = currtime - 12 else: currtime = currtime - 12 else: daytime = "a.m." # convert time to textual time if currtime == 0: t = __fig(currtime)+" o'clock" if currtime != 0 else __fig(currtime) elif currtime > 30: t = __fig((60 - currtime))+" to "+__fig(currtime+1) else: t = __fig(currtime)+" past "+__fig(currtime) return [t, period, daytime, currtime, speak]
This is the actual indicator. Copy the code, save it as
moderntimes.py, together with the icon and th module above in one and the same directory.
#!/usr/bin/env python3 import os import signal import subprocess import gi gi.require_version('Gtk', '3.0') from gi.repository import Gtk, AppIndicator3, GObject import time from threading import Thread import tcalc # --- define what to show: # showtime = textual time, daytime = a.m./p.m. period = "night"/"morning"/day"/"evening" # speak = speak out time every quarter, fuzzy = round time on 5 minutes showtime = True; daytime = False; period = True; speak = True; fuzzy = True class Indicator(): def __init__(self): self.app = 'about_time' path = os.path.dirname(os.path.abspath(__file__)) self.indicator = AppIndicator3.Indicator.new( self.app, os.path.abspath(path+"/indicator_icon.png"), AppIndicator3.IndicatorCategory.OTHER) self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE) self.indicator.set_menu(self.create_menu()) self.update = Thread(target=self.get_time) self.update.setDaemon(True) self.update.start() def get_time(self): # the first loop is 0 seconds, the next loop is 60 seconds, # in phase with computer clock loop = 0; timestring1 = "" while True: time.sleep(loop) tdata = tcalc.textualtime(fuzzy) timestring2 = tdata loop = (60 - tdata)+1 mention = (" | ").join([tdata[item] for item in [ [showtime, 0], [period, 1], [daytime, 2] ]if item == True]) if all([ tdata == True, speak == True, timestring2 != timestring1, ]): subprocess.Popen(["espeak", '"'+timestring2+'"', "-s", "130"]) #  edited GObject.idle_add( self.indicator.set_label, mention, self.app, priority=GObject.PRIORITY_DEFAULT ) timestring1 = timestring2 def create_menu(self): menu = Gtk.Menu() item_quit = Gtk.MenuItem('Quit') item_quit.connect('activate', self.stop) menu.append(item_quit) menu.show_all() return menu def stop(self, source): Gtk.main_quit() Indicator() GObject.threads_init() signal.signal(signal.SIGINT, signal.SIG_DFL) Gtk.main()
How to use
The script needs
sudo apt-get install espeak
Copy all three files above into one and the same directory, exactly named as indicated in The script, the module and an icon
In the head of the script (
moderntimes.py), define which information should be displayed, and how. Simply set
Falsein the line:
# --- define what to show: # time = textual time, daytime = a.m./p.m. period = "night"/"morning"/day"/"evening" # speak = speak out time every quarter, fuzzy = round time on 5 minutes showtime = True; daytime = False; period = True; speak = False; fuzzy = True
In the head of the module, you can change the hours when to start subsequently morning, day, evening, night, in the line:
# --- set starttime of morning, day, evening, night (whole hrs) limits = [6, 9, 18, 21] # ---
Don't touch anything else in the script for now :)
Ubuntu Mate users need to enable the use of indicators on their system: choose System > Preferences > Look and feel > Mate tweak > Interface > "Enable indicators"
Run the indicator with the command:
Running it from Startup Applications
Remember that if you run the command from Startup Applications, in many cases you need to add a little break, especially (among others) on indicators:
/bin/bash -c "sleep 15 && python3 /path/to/moderntimes.py"
No doubt the script will be changed/updated in the next few days many times. One thing I'd like feedback on in particular is the "style" in which the digital time is converted into textual time. The way it is done now:
whole hours, e.g.:
less then 30 mins after the hour, e.g.
twenty past eleven
30 mins after the hour e.g.:
half past five
more the 30 mins e.g.:
twenty to five
15 minutes are mentioned
quarter past six
exception is midnight, which is not called
quarter past midnight
The script is extremely low on juice, due to the fact that after the first timecheck- loop, the loop is synchronized on the computer clock automatically. Therefore the script checks time/edits the displayed time only once per minute, sleeping the rest of the time.
As per today (2016-4-9), a ppa of a polished version is available. To install from ppa:
sudo apt-add-repository ppa:vlijm/abouttime sudo apt-get update sudo apt-get install abouttime
The day periods in this version are changed, compared to the script version above, now it is:
morning 6:00-12:00 afternoon 12:00-18:00 evening 18:00-24:00 night 24:00-6:00
As mentioned, this version was tested on both
Mate (from the original question)
If you have Kubuntu (Plasma Desktop Ubuntu distro), you have a built-in widget called "fuzzy clock" -- it's been around at least since 14.04, or as long ago as Plasma 4 has been out, and it's still in Plasma 5 as found in Kubuntu 16.04.
Fuzzy Clock can be set to be as "accurate" as five minute increments, like reading an analog clock (say, "ten after four"), but it also has three "fuzzier" settings, one of which gives readings like "afternoon" and one that just gives "Weekend!" (on a Sunday afternoon -- I presume it'll say "Monday" tomorrow).
I don't know if fuzzy clock is available in other Ubuntu flavors -- I saw it in xfce (as found in Xubuntu) on my system, but the OS was installed as Kubuntu, so I'm not sure if the fuzzy clock is native to xfce as well as KDE/Plasma, nor whether it's available in Unity or Mate.