Skip to content

Instantly share code, notes, and snippets.

@wjt
Last active April 3, 2017 10:48
Show Gist options
  • Save wjt/fec8f3b79fd4b679bedfac4d435f670c to your computer and use it in GitHub Desktop.
Save wjt/fec8f3b79fd4b679bedfac4d435f670c to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
import bs4
import json
import logging
import os
import requests
log = logging.getLogger(__name__)
def xdg_cache_home():
try:
return os.environ['XDG_CACHE_HOME']
except KeyError:
return os.path.expanduser('~/.cache')
URL = 'https://endlessos.com/download/'
SELECTOR = '#version optgroup option'
CACHE = os.path.join(xdg_cache_home(), os.path.basename(__file__) + '.json')
RELEASES_JSON = 'https://d1anzknqnc1kmb.cloudfront.net/releases-eos-3.json'
class CheckFailedError(Exception):
pass
def die(message, *args):
raise CheckFailedError(message % args)
def check_website():
log.info("Fetching %s", URL)
r = requests.get(URL)
r.raise_for_status()
html = r.text
log.info("Finding download options")
soup = bs4.BeautifulSoup(html, "lxml")
opts = soup.select(SELECTOR)
if len(opts) == 0:
die("No download options found")
urls = [o.attrs['value'] for o in opts]
n = len(urls)
log.info("%d download URLs:\n%s", n, "\n".join(urls))
try:
log.info("Loading %s", CACHE)
with open(CACHE, 'r') as f:
cache = json.load(f)
except FileNotFoundError:
pass
else:
log.info("Loaded cache, checking options haven't decreased")
cache_urls = cache['urls']
m = len(cache_urls)
log.info("%d cached urls:\n%s", m, "\n".join(cache_urls))
if m > n:
die("Number of download options fell from %d to %d", m, n)
log.info("Persisting URL list to %s", CACHE)
with open(CACHE, 'w') as f:
json.dump({'urls': urls}, f)
def check_releases():
r = requests.get(RELEASES_JSON)
r.raise_for_status()
j = r.json()
if not j['images']:
raise CheckFailedError('no images in json: %s', j)
log.info('%s has some images, at least', RELEASES_JSON)
# TODO: more thorough checks? Don't want to cross-check with website
# because we know the website lags by up to an hour…
def main():
logging.basicConfig(
level='INFO',
format='%(asctime)s %(levelname)8s [%(name)s] %(message)s')
checks = [
check_releases,
check_website,
]
errors = False
for c in checks:
try:
c()
except Exception:
log.error('%s failed', c.__name__, exc_info=True)
errors = True
if errors:
raise SystemExit(1)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment