Created
May 2, 2017 00:00
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- 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