presto2gemini/presto2gemini.py

188 lines
5.7 KiB
Python
Executable File

#!/usr/bin/env python3
"""A program to retrieve Presto solar storm alerts
<http://www.sidc.be/products/presto/> and transform them to gemtext
<https://gemini.circumlunar.space/>.
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)