diff options
-rwxr-xr-x | blue.py | 206 |
1 files changed, 206 insertions, 0 deletions
@@ -0,0 +1,206 @@ +#!/usr/bin/env python3 +# See LICENSE file for copyright and license details. + +import sys, os, pwd, time +import solar_python as sol + + +loc = None +stop_date = None +human = False +noon = False +blue = False +gold = False +unblue = False +ungold = False +morning = [] +evening = [] +deriv = [] + + +## Parse command line +argv0 = sys.argv[0] if len(sys.argv) > 0 else 'blue' +def usage(): + opts = '[-e elev]* [-m elev]* [-d delev]* [-l lat:lon | -l loc] [-s year-month-day | -s -] [-bBgGhn]' + print('Usage: %s %s' % (argv0, opts), file = sys.stderr) + sys.exit(1) +i, n = 1, len(sys.argv) +def getarg(): + global i, j, n, m + if j < m: + rc = arg[j] + j = m + return rc + else: + j = m + i += 1 + if i == n: + usage() + return sys.argv[i] +while i < n: + arg = sys.argv[i] + if arg == '--': + i += 1 + break + elif arg.startwith('-'): + j, m = 1, len(arg) + while j < m: + c = arg[j] + j += 1 + if c == 'd': + deriv.append(getarg()) + elif c == 'e': + evening.append(getarg()) + elif c == 'm': + morning.append(getarg()) + elif c == 'l': + loc = getarg() + elif c == 's': + stop_date = getarg() + elif c == 'b': + blue = True + elif c == 'B': + unblue = True + elif c == 'g': + gold = True + elif c == 'G': + ungold = True + elif c == 'h': + human = True + elif c == 'n': + noon = True + else: + usage() + j += 1 + i += 1 + else: + break +if i != n: + usage() + + +## Parse elevations +try: + evening = [float(e) for e in evening] + morning = [float(e) for e in morning] + deriv = [float(e) for e in deriv] + for e in evening + morning: + if abs(e) > 90: + usage() +except: + usage() + + +## Parse -bBgGn +if blue: + morning.append(sol.SOLAR_ELEVATION_RANGE_BLUE_HOUR[0]) + evening.append(sol.SOLAR_ELEVATION_RANGE_BLUE_HOUR[1]) +if unblue: + morning.append(sol.SOLAR_ELEVATION_RANGE_BLUE_HOUR[1]) + evening.append(sol.SOLAR_ELEVATION_RANGE_BLUE_HOUR[0]) +if gold: + morning.append(sol.SOLAR_ELEVATION_RANGE_GOLDEN_HOUR[0]) + evening.append(sol.SOLAR_ELEVATION_RANGE_GOLDEN_HOUR[1]) +if ungold: + morning.append(sol.SOLAR_ELEVATION_RANGE_GOLDEN_HOUR[1]) + evening.append(sol.SOLAR_ELEVATION_RANGE_GOLDEN_HOUR[0]) +if noon: + deriv.append(0.0) + + +## Fallback options +if len(morning) == 0 and len(evening) == 0 and len(deriv) == 0: + morning.append(sol.SOLAR_ELEVATION_RANGE_BLUE_HOUR[0]) + evening.append(sol.SOLAR_ELEVATION_RANGE_BLUE_HOUR[1]) + + +## Get geolocation +def get_geolocation_from_conf(filename, ispath = False): + filenames, lat, lon = [], None, None + if ispath: + filenames.append(filename) + else: + if 'HOME' in os.environ and len(os.environ['HOME']) > 0: + filenames.append(os.environ['HOME'] + '/.config/' + filename) + try: + filenames.append(pwd.getpwuid(os.getuid()).pw_dir + '/.config/' + filename) + except: + pass + filenames.append('/etc/' + filename) + for filename in filenames: + try: + with open(filename, 'rb') as file: + loc = file.read().decode('utf-8', 'replace').split('\n')[0] + (lat, lon) = loc.split(' ') + lat, lon = float(lat), float(lon) + break + except: + lat, lon = None, None + return (lat, lon) +if loc is not None: + try: + (lat, lon) = loc.split(':') + lat = float(lat) + lon = float(lon) + if (abs(lat) > 90 or abs(lon) > 180): + lat = None + except: + lat = None + if lat is None: + if loc.startswith('./') or loc.startswith('../') or loc.startswith('/'): + locfile = loc + else: + locfile = 'geolocation.d/' + loc + (lat, lon) = get_geolocation_from_conf(locfile, locfile is loc) + if lat is None: + print('%s: bad location: %s' % (argv0, loc), file = sys.stderr) + sys.exit(1) +else: + (lat, lon) = get_geolocation_from_conf('geolocation') + if lat is None: + print('%s: no geolocation set' % argv0, file = sys.stderr) + sys.exit(1) + + +## Parse stop date +if stop_date is not None: + if stop_date == '-': + stop_date = ... + else: + try: + tm = time.strptime(stop_date, '%Y-%m-%d') + stop_date = (tm.tm_year, tm.tm_mon, tm.tm_mday) + except: + usage() +else: + tm = time.localtime() + if tm.tm_mon < 12: + stop_date = (tm.tm_year, tm.tm_mon + 1, tm.tm_mday) + else: + stop_date = (tm.tm_year + 1, 1, tm.tm_mday) + + +## Get stop time +if stop_date is ...: + stop_time = None +else: + stop_time = '%i-%02i-%02i 12:00:00' % stop_date + guessed = time.mktime(time.strptime(stop_time, '%Y-%m-%d %H:%M:%S')) + is_summer = False + for tzname, summer in zip(time.tzname, (False, True)): + if time.mktime(time.strptime('%s %s' % (stop_time, tzname), '%Y-%m-%d %H:%M:%S %Z')) == guessed: + is_summer = summer + break + (y, m, d) = stop_date + days = 29 if y % 400 == 0 or (y % 4 == 0 and not y % 100 == 0) else 28 + days = [31, days, 31, 30, 31, 30, 30, 31, 30, 31, 30, 31] + stop_time = d - 1 + for i in range(m - 1): + stop_time += days[i] + y -= 1 + stop_time += y * 365 + y // 4 - y // 100 + y // 400 + stop_time -= 1969 * 365 + 1969 // 4 - 1969 // 100 + 1969 // 400 + stop_time *= 24 * 60 * 60 + stop_time += 24 * 60 * 60 + stop_time -= (time.altzone if is_summer else time.timezone) + |