planet.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import re
import subprocess
import rose.macro
class PlanetChecker(rose.macro.MacroBase):
"""Checks option values that refer to planets."""
error_text = "planet is too far away."
opts_to_check = [("env", "WORLD")]
def validate(self, config, meta_config=None):
"""Return a list of errors, if any."""
allowed_planets = self._get_allowed_planets()
for section, option in self.opts_to_check:
node = config.get([section, option])
if node is None or node.is_ignored():
continue
if node.value not in allowed_planets:
self.add_report(section, option, node.value, self.error_text)
return self.reports
def _get_allowed_planets(self):
# Retrieve planets less than a certain distance away.
cmd_strings = ["curl", "-s",
"http://www.heavens-above.com/planetsummary.aspx"]
p = subprocess.Popen(cmd_strings, stdout=subprocess.PIPE)
text = p.communicate()[0]
planets = re.findall("(\w+)</td>",
re.sub(r'(?s)^.*(<thead.*?ascension).*$',
r"\1", text))
distances = re.findall("([\d.]+)</td>",
re.sub('(?s)^.*(Range.*?Brightness).*$',
r"\1", text))
for planet, distance in zip(planets, distances):
if float(distance) > 5.0:
# The planet is more than 5 AU away.
planets.remove(planet)
planets += ["Earth"] # Distance ~ 0
return planets