#!/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)