#!/usr/bin/env python3 """A program to retrieve Presto solar storm alerts and transform them to gemtext . Run it from cron from time to time. """ # Standard library import getopt import time import sys import re import os import shutil # Other libraries # http://python-requests.org/ import requests PRESTO_URL = "https://www.sidc.be/spaceweatherservices/managed/services/applications/managed/services/archive/product/presto" SOURCE_URL = "https://forge.chapril.org/bortzmeyer/presto2gemini" # Defaults date = time.strftime("%Y-%m-%d", time.gmtime(time.time())) dest_dir = "/var/gemini/presto" raw_file_dir = dest_dir + "/raw-files" maintainer = "Stéphane Bortzmeyer stephane+gemini@bortzmeyer.org" verbose = False index = True force_index = False input = None def usage(msg=None): print("Usage: %s [--date YYYY-MM-DD] [--destination STRING] [--raw-directory] [--verbose]" % sys.argv[0], file=sys.stderr) if msg is not None: print(msg, file=sys.stderr) def create_index(gem_dir, raw_dir): f = open("%s%s" % (gem_dir, "index.gmi"), "w") print("""# List of Presto solar storms alerts From the alerts sent by SIDC (Solar Influences Data analysis Center). => http://www.sidc.be/products/presto/ SIDC Presto reference site => https://en.wikipedia.org/wiki/Solar_storm Wikipedia on solar storms """, file=f) files = [] for file in os.listdir(raw_dir): files.append(file) sorted_files = sorted(files, reverse=True) if len(sorted_files) != 0: fs = open("%s%s.txt" % (gem_dir, sorted_files[0]), "r") print(""" Last alert: %s """ % fs.read(), file=f) fs.close() for file in sorted(files, reverse=True): print("=> %s.gmi Alert of %s" % (file, file), file=f) print(""" ## Legal and contact ### This Gemini mirror Maintained by %s from the SIDC data. => %s Source code for the conversion program ### SIDC - Solar Influences Data analysis Center - RWC Belgium Royal Observatory of Belgium => http://www.sidc.be/ Website E-mail sidc-support@oma.be => http://www.astro.oma.be/common/internet/en/data-policy-en.pdf Intellectual Property Rights => http://www.astro.oma.be/common/internet/en/disclaimer-en.pdf Liability Disclaimer => http://www.astro.oma.be/common/internet/en/privacy-policy-en.pdf Use and processing of your personal information """ % (maintainer, SOURCE_URL), file=f) f.close() try: optlist, args = getopt.getopt (sys.argv[1:], "d:vi", ["date=", "help", "verbose", "force-index", "no-index", "destination=", "source=", "input="]) for option, value in optlist: if option == "--help" or option == "-h": usage() sys.exit(0) elif option == "--date" or option == "-d": date = value # TODO check the syntax? elif option == "--destination": dest_dir = value elif option == "--destination": raw_dir = value elif option == "--source": raw_file_dir = value elif option == "--verbose" or option == "-v": verbose = True elif option == "--force-index" or option == "-i": force_index = True elif option == "--no-index": index = False elif option == "--input": input = value else: # Should never occur, it is trapped by getopt usage("Unknown option %s" % option) except getopt.error as reason: usage(reason) sys.exit(1) if len(args) != 0: usage() sys.exit(1) urlpath = date.replace("-", "/") url = "%s/%s" % (PRESTO_URL, urlpath) if not raw_file_dir.endswith("/"): raw_file_dir += "/" if not dest_dir.endswith("/"): dest_dir += "/" input_ok = False if input is None: r = requests.get(url, allow_redirects = False) if r.status_code != 200: print("Wrong status code %s from %s" % (r.status_code, PRESTO_URL), file=sys.stderr) sys.exit(1) if r.status_code == 200 and r.text != "" and r.text != "\r\n" and r.text != "\n": # Yes, # when there is no alert, they reply with 200 and an empty file :-( raw = open("%s%s" % (raw_file_dir, date), "w") print(r.text, file=raw) raw.close() input_ok = True else: shutil.copyfile(input, "%s%s" % (raw_file_dir, date)) input_ok = True if input_ok: gemfile = open ("%s%s.gmi" % (dest_dir, date), "w") txtfile = open ("%s%s.txt" % (dest_dir, date), "w") raw = open("%s%s" % (raw_file_dir, date), "r") print(""" # Solar alert """, file=gemfile) for line in raw.readlines(): line=line[:-1] # Chop end-of-line if re.search("^\s*#", line): continue # Ignore comments else: match = re.search("^\s*:([a-zA-Z]+):\s*(.*)", line) if match: if match.group(1) == "Issued": issued = match.group(2) print(""" Issued on %s """ % issued, file=gemfile) print(""" Issued on %s """ % issued, file=txtfile) continue # Ignore other metadata else: print(line, file=gemfile, end=" ") print(line, file=txtfile, end=" ") if line == "": print("", file=gemfile) print("", file=txtfile) print(""" => %s Reference for this alert => /presto/ All Presto solar alerts """ % url, file=gemfile) raw.close() gemfile.close() txtfile.close() if index: create_index(dest_dir, raw_file_dir) elif force_index and index: create_index(dest_dir, raw_file_dir)