bumblebee-status/modules/core/redshift.py

134 lines
4.2 KiB
Python
Raw Normal View History

2020-03-07 14:06:01 +01:00
# pylint: disable=C0111,R0903
2020-03-07 14:06:18 +01:00
'''Displays the current color temperature of redshift
2020-03-07 14:06:01 +01:00
Requires the following executable:
* redshift
Parameters:
* redshift.location : location provider, either of 'auto' (default), 'geoclue2',
'ipinfo' (requires the requests package), or 'manual'
'auto' uses whatever redshift is configured to do
2020-03-07 14:06:18 +01:00
* redshift.lat : latitude if location is set to 'manual'
* redshift.lon : longitude if location is set to 'manual'
'''
2020-03-07 14:06:01 +01:00
import threading
import logging
log = logging.getLogger(__name__)
2020-03-07 14:06:01 +01:00
try:
import requests
except ImportError:
log.warning('unable to import module "requests": Location via IP disabled')
2020-03-07 14:06:01 +01:00
import core.module
import core.widget
import core.input
2020-03-07 14:06:01 +01:00
import util.cli
2020-03-07 14:06:01 +01:00
def is_terminated():
for thread in threading.enumerate():
2020-03-07 14:06:18 +01:00
if thread.name == 'MainThread' and not thread.is_alive():
2020-03-07 14:06:01 +01:00
return True
return False
def get_redshift_value(widget, location, lat, lon):
while True:
if is_terminated():
return
2020-03-07 14:06:18 +01:00
widget.get('condition').acquire()
2020-03-07 14:06:01 +01:00
while True:
try:
2020-03-07 14:06:18 +01:00
widget.get('condition').wait(1)
2020-03-07 14:06:01 +01:00
except RuntimeError:
continue
break
2020-03-07 14:06:18 +01:00
widget.get('condition').release()
2020-03-07 14:06:01 +01:00
command = ['redshift', '-p']
2020-03-07 14:06:18 +01:00
if location == 'manual':
command.extend(['-l', '{}:{}'.format(lat, lon)])
if location == 'geoclue2':
command.extend(['-l', 'geoclue2'])
2020-03-07 14:06:01 +01:00
try:
res = util.cli.execute(' '.join(command))
2020-03-07 14:06:01 +01:00
except Exception:
2020-03-07 14:06:18 +01:00
res = ''
widget.set('temp', 'n/a')
widget.set('transition', None)
widget.set('state', 'day')
for line in res.split('\n'):
2020-03-07 14:06:01 +01:00
line = line.lower()
2020-03-07 14:06:18 +01:00
if 'temperature' in line:
widget.set('temp', line.split(' ')[2])
if 'period' in line:
state = line.split(' ')[1]
if 'day' in state:
widget.set('state', 'day')
elif 'night' in state:
widget.set('state', 'night')
2020-03-07 14:06:01 +01:00
else:
2020-03-07 14:06:18 +01:00
widget.set('state', 'transition')
widget.set('transition', ' '.join(line.split(' ')[2:]))
2020-03-07 14:06:01 +01:00
class Module(core.module.Module):
def __init__(self, config=None):
widget = core.widget.Widget(self.text)
super().__init__(config, widget)
2020-03-07 14:06:01 +01:00
self._location = self.parameter('location', 'auto')
2020-03-07 14:06:18 +01:00
self._lat = self.parameter('lat', None)
self._lon = self.parameter('lon', None)
2020-03-07 14:06:01 +01:00
# Even if location method is set to manual, if we have no lat or lon,
# fall back to the geoclue2 method.
#
2020-03-07 14:06:18 +01:00
if self._location == 'manual' and (self._lat is None
2020-03-07 14:06:01 +01:00
or self._lon is None):
2020-03-07 14:06:18 +01:00
self._location == 'geoclue2'
2020-03-07 14:06:01 +01:00
2020-03-07 14:06:18 +01:00
if self._location == 'ipinfo':
2020-03-07 14:06:01 +01:00
try:
2020-03-07 14:06:18 +01:00
location_url = 'http://ipinfo.io/json'
2020-03-07 14:06:01 +01:00
location = requests.get(location_url).json()
2020-03-07 14:06:18 +01:00
self._lat, self._lon = location['loc'].split(',')
2020-03-07 14:06:01 +01:00
self._lat = str(float(self._lat))
self._lon = str(float(self._lon))
2020-03-07 14:06:18 +01:00
self._location = 'manual'
2020-03-07 14:06:01 +01:00
except Exception:
# Fall back to geoclue2.
2020-03-07 14:06:18 +01:00
self._location = 'geoclue2'
2020-03-07 14:06:01 +01:00
2020-03-07 14:06:18 +01:00
self._text = ''
2020-03-07 14:06:01 +01:00
self._condition = threading.Condition()
2020-03-07 14:06:18 +01:00
widget.set('condition', self._condition)
2020-03-07 14:06:01 +01:00
self._thread = threading.Thread(target=get_redshift_value,
args=(widget, self._location,
self._lat, self._lon))
2020-03-07 14:06:01 +01:00
self._thread.start()
self._condition.acquire()
self._condition.notify()
self._condition.release()
def text(self, widget):
2020-03-07 14:06:18 +01:00
return '{}'.format(self._text)
2020-03-07 14:06:01 +01:00
def update(self):
widget = self.widget()
2020-03-07 14:06:01 +01:00
self._condition.acquire()
self._condition.notify()
self._condition.release()
2020-03-07 14:06:18 +01:00
temp = widget.get('temp', 'n/a')
2020-03-07 14:06:01 +01:00
self._text = temp
2020-03-07 14:06:18 +01:00
transition = widget.get('transition', None)
2020-03-07 14:06:01 +01:00
if transition:
2020-03-07 14:06:18 +01:00
self._text = '{} {}'.format(temp, transition)
2020-03-07 14:06:01 +01:00
def state(self, widget):
2020-03-07 14:06:18 +01:00
return widget.get('state', None)
2020-03-07 14:06:01 +01:00
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4