Skip to content

Instantly share code, notes, and snippets.

@soulshake
Created May 2, 2017 00:00
Show Gist options
  • Save soulshake/50ad1e3f6ff51681a9e7a84dd155e918 to your computer and use it in GitHub Desktop.
Save soulshake/50ad1e3f6ff51681a9e7a84dd155e918 to your computer and use it in GitHub Desktop.
Not really fully working but semi-close maybe way to display a clickable series of timezones in i3 status bar
# -*- coding: utf-8 -*-
"""
Cycle Timezones
py3status module that manually cycles through a set of timezones when clicked.
Configuration parameters:
format: Initial format to use
(default "")
format_clicked: Display format to use when we are clicked
(default "")
show_zone_name: Display human-friendly timezone name (e.g. America/Chicago)
(default False)
local_time_color: hex code if you want your current local timezone to be highlighted
(default: "#FF00FF")
arrow_date_format: Format to use when displaying date
(default: "ddd DD MMM H:mma Z")
Format placeholders:
{button} The button that was pressed
Color options:
local_time_color: Current local timezone, defaults to color_good (#FIXME)
Requires:
arrow: `pip install arrow`
Example:
```
order += "timezones"
...
timezones {
click_mode = "button"
local_time_color = "#00FF00"
arrow_date_format = "ddd DD MMM H:mma Z"
zones = [
"America/Los_Angeles",
"America/Chicago",
"Europe/Berlin",
"America/New_York",
"Europe/Moscow",
]
}
```
To do:
Convert from i3 date format to arrow.
@author AJ Bowen (GitHub: @soulshake)
@license MIT
"""
import arrow
class Py3status:
local_time_color = None
#py3_date_format = "%a %b %d %H:%M:%S %Z"
show_zone_name = None
format_open = "ddd DD, YYYY"
format_closed = "ddd DD"
button_toggle = None
format = ""
def __init__(self, zones=[]):
self.open = True
self.button = None
# Set default timezones if none have been provided.
if not zones:
zones = [
"Europe/Berlin",
"America/Los_Angeles",
"America/Chicago",
"America/New_York",
]
# Add local timezone if not already present
with open("/etc/timezone", 'r') as f:
local = f.read().strip('\n')
if local not in zones:
zones.insert(0, local)
# Show local time by default at first.
self.i = zones.index(local)
self.is_first_display = True
self.zones = zones
self.local = local
self.full_text = local
def post_config_hook(self):
self.open = False
if '{button}' not in self.format:
self.open = True
if not self.local_time_color:
self.local_time_color = self.py3.COLOR_GOOD
if self.show_zone_name is None:
self.show_zone_name = True
def click_info(self):
"""
This method is executed every time our module is clicked,
as well as whenever the cache expires (in which case self.button will be None).
"""
if self.is_first_display:
self.i = self.zones.index(self.local)
self.is_first_display = False
#ret = {'cached_until': self.py3.CACHE_FOREVER,
ret = {'cached_until': self.py3.time_in(seconds=20),
"full_text": self._get_full_text()
#'composite': self._get_composite()
#'color': "#99FF44"
}
return ret
def _get_composite(self):
comp = []
# Part I: Date
comp.append({"full_text": "date", "index": 0})
# Part II: Time
comp.append({"full_text": "time", "index": 1})
# Part III: Button
comp.append({"full_text": "button", "index": 2})
ret = {
'cached_until': self.py3.CACHE_FOREVER,
'composite': comp,
}
return ret
def _get_short_timezone(self, zone):
now = arrow.now(zone)
return now.tzinfo.tzname(now)
def _get_full_text(self):
zone = self.zones[self.i]
now = arrow.now(zone)
shorttz = self._get_short_timezone(zone)
self.py3.log(shorttz)
if self.open:
full_text = now.format(self.format_open)
if self.show_zone_name:
full_text = "{} {}".format(full_text, zone)
else:
full_text = now.format(self.format_closed)
full_text = "{} {}".format(full_text, shorttz)
return full_text
def on_click(self, event):
"""
Cycle through timezones when user clicks the i3 module.
This method processes each click event.
event will be a dict like:
{'y': 13, 'x': 1737, 'button': 1, 'name': 'example', 'instance': 'first'}
All we need to do here is keep track of our location in the list of timezones.
The timezones method will take care of the rest.
"""
#self.button = event['button']
if event['button'] == self.button_toggle:
self.open = not self.open
self.py3.log(self.button_toggle)
self.py3.log("\n\nReceived event: {}\n\n".format(event))
self.py3.log("Got click from button {}".format(event['button']))
#if event['button'] == self.button_toggle:
## we only toggle if button was used
#if event.get('index') == 'button' and self.py3.is_my_event(event):
#self.open = not self.open
# Left-click or scroll down cycles through timezones.
if event['button'] in [1, 5, 8]:
delta = 1
# Right-click or scroll up goes backwards.
elif event['button'] in [3, 4, 9]:
delta = -1
# Always return to current local timezone on middle click.
elif event['button'] in [2]:
delta = (self.i * -1) + (self.zones.index(self.local))
# Otherwise, do nothing.
else:
delta = (self.i * -1) + (self.zones.index(self.local))
new_i = self.i + delta
if new_i >= len(self.zones):
self.i = 0
elif new_i < 0:
self.i = len(self.zones) - 1
else:
self.i = new_i
def timezones(self):
"""
Display the date and time in the requested timezone.
Highlight local time when cycling through the list.
NOTE: This py3status module uses arrow for date/time formatting, not i3.
i3 date formats will not work as expected.
See: http://crsmithdev.com/arrow/#format
"""
zone = self.zones[self.i]
now = arrow.now(zone)
response = {}
now = now.format(" h:mma")
#response['full_text'] = self._get_full_text()
response['full_text'] = now
if zone == self.local:
response['color'] = self.local_time_color
return response
if __name__ == "__main__":
"""
Run module in test mode.
"""
config = {
'always_show': True,
}
from py3status.module_test import module_test
module_test(Py3status, config=config)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment