From 73ca0395d638a0cf22eb135ad554a43a30176b5a Mon Sep 17 00:00:00 2001 From: Stephane Bortzmeyer Date: Sat, 27 Mar 2021 13:13:59 +0100 Subject: [PATCH] First code import --- README.md | 23 +++++- presto2gemini.py | 178 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 200 insertions(+), 1 deletion(-) create mode 100755 presto2gemini.py diff --git a/README.md b/README.md index f164c4a..d67ee55 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,24 @@ # presto2gemini -Download solar storm alerts from the Presto service and converts them into gemtext (text/gemini) to be served via Gemini. \ No newline at end of file +Download [solar storm](https://en.wikipedia.org/wiki/Solar_storm) alerts from the [Presto service](http://www.sidc.be/products/presto/) and converts them +into gemtext (`text/gemini`) to be served via +[Gemini](https://en.wikipedia.org/wiki/Gemini_(protocol)). + +The result can be seen (if you have a Gemini browser( [on my Gemini capsule](gemini://gemini.bortzmeyer.org/presto/). + +## Installation + +Download the program, Be sure you have the [Python requests +library](http://python-requests.org/) then run the program periodically, for instance through +cron: + +``` +# Solar alerts +33 3,7,11,15,19,23 * * * /path/to/program/presto2gemini.py +``` + +## Technical details + +We start from plain text files like [this +alert](http://www.sidc.be/archive/product/presto/2020/12/13) since +Presto alerts are not available in a structured format. diff --git a/presto2gemini.py b/presto2gemini.py new file mode 100755 index 0000000..937262d --- /dev/null +++ b/presto2gemini.py @@ -0,0 +1,178 @@ +#!/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 = "http://www.sidc.be/archive/product/presto" + +# Defaults +date = time.strftime("%Y-%m-%d", time.gmtime(time.time())) +dest_dir = "/var/gemini/presto" +raw_file_dir = "/home/stephane/Gemini/PrestoAlert/raw-files" +verbose = False +index = True +force_index = False +input = None + +def usage(msg=None): + print("Usage: %s [--date YYYY-MM-DD] [--destination STRING] [--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) + 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 Stéphane Bortzmeyer stephane+gemini@bortzmeyer.org from the SIDC data. + +### 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 +""", 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 == "--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 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)